d3d9/tests: Add a test for cube texture mipmap autogeneration.
[wine.git] / dlls / d3d9 / tests / visual.c
blob0439ebd52ee7a933de506f8ca6dca210733a277b
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 HWND hwnd;
55 RECT rect;
57 SetRect(&rect, 0, 0, 640, 480);
58 AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE);
59 hwnd = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
60 0, 0, rect.right - rect.left, rect.bottom - rect.top, 0, 0, 0, 0);
61 return hwnd;
64 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
66 if (abs((int)(c1 & 0xff) - (int)(c2 & 0xff)) > max_diff) return FALSE;
67 c1 >>= 8; c2 >>= 8;
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 return TRUE;
76 static BOOL adapter_is_warp(const D3DADAPTER_IDENTIFIER9 *identifier)
78 return !strcmp(identifier->Driver, "d3d10warp.dll");
81 /* Locks a given surface and returns the color at (x,y). It's the caller's
82 * responsibility to only pass in lockable surfaces and valid x,y coordinates */
83 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
85 DWORD color;
86 HRESULT hr;
87 D3DSURFACE_DESC desc;
88 RECT rectToLock = {x, y, x+1, y+1};
89 D3DLOCKED_RECT lockedRect;
91 hr = IDirect3DSurface9_GetDesc(surface, &desc);
92 if(FAILED(hr)) /* This is not a test */
94 trace("Can't get the surface description, hr=%08x\n", hr);
95 return 0xdeadbeef;
98 hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
99 if(FAILED(hr)) /* This is not a test */
101 trace("Can't lock the surface, hr=%08x\n", hr);
102 return 0xdeadbeef;
104 switch(desc.Format) {
105 case D3DFMT_A8R8G8B8:
107 color = ((DWORD *) lockedRect.pBits)[0];
108 break;
110 default:
111 trace("Error: unknown surface format: %d\n", desc.Format);
112 color = 0xdeadbeef;
113 break;
115 hr = IDirect3DSurface9_UnlockRect(surface);
116 if(FAILED(hr))
118 trace("Can't unlock the surface, hr=%08x\n", hr);
120 return color;
123 struct surface_readback
125 IDirect3DSurface9 *surface;
126 D3DLOCKED_RECT locked_rect;
129 static void get_rt_readback(IDirect3DSurface9 *surface, struct surface_readback *rb)
131 IDirect3DDevice9 *device;
132 D3DSURFACE_DESC desc;
133 HRESULT hr;
135 memset(rb, 0, sizeof(*rb));
136 hr = IDirect3DSurface9_GetDevice(surface, &device);
137 ok(SUCCEEDED(hr), "Failed to get device, hr %#x.\n", hr);
138 hr = IDirect3DSurface9_GetDesc(surface, &desc);
139 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
140 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, desc.Width, desc.Height,
141 desc.Format, D3DPOOL_SYSTEMMEM, &rb->surface, NULL);
142 if (FAILED(hr) || !rb->surface)
144 trace("Can't create an offscreen plain surface to read the render target data, hr %#x.\n", hr);
145 goto error;
148 hr = IDirect3DDevice9_GetRenderTargetData(device, surface, rb->surface);
149 if (FAILED(hr))
151 trace("Can't read the render target data, hr %#x.\n", hr);
152 goto error;
155 hr = IDirect3DSurface9_LockRect(rb->surface, &rb->locked_rect, NULL, D3DLOCK_READONLY);
156 if (FAILED(hr))
158 trace("Can't lock the offscreen surface, hr %#x.\n", hr);
159 goto error;
161 IDirect3DDevice9_Release(device);
163 return;
165 error:
166 if (rb->surface)
167 IDirect3DSurface9_Release(rb->surface);
168 rb->surface = NULL;
169 IDirect3DDevice9_Release(device);
172 static DWORD get_readback_color(struct surface_readback *rb, unsigned int x, unsigned int y)
174 return rb->locked_rect.pBits
175 ? ((DWORD *)rb->locked_rect.pBits)[y * rb->locked_rect.Pitch / sizeof(DWORD) + x] : 0xdeadbeef;
178 static void release_surface_readback(struct surface_readback *rb)
180 HRESULT hr;
182 if (!rb->surface)
183 return;
184 if (rb->locked_rect.pBits && FAILED(hr = IDirect3DSurface9_UnlockRect(rb->surface)))
185 trace("Can't unlock the offscreen surface, hr %#x.\n", hr);
186 IDirect3DSurface9_Release(rb->surface);
189 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
191 DWORD ret;
192 IDirect3DSurface9 *rt;
193 struct surface_readback rb;
194 HRESULT hr;
196 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
197 if(FAILED(hr))
199 trace("Can't get the render target, hr %#x.\n", hr);
200 return 0xdeadbeed;
203 get_rt_readback(rt, &rb);
204 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
205 * really important for these tests
207 ret = get_readback_color(&rb, x, y) & 0x00ffffff;
208 release_surface_readback(&rb);
210 IDirect3DSurface9_Release(rt);
211 return ret;
214 static IDirect3DDevice9 *create_device(IDirect3D9 *d3d, HWND device_window, HWND focus_window, BOOL windowed)
216 D3DPRESENT_PARAMETERS present_parameters = {0};
217 IDirect3DDevice9 *device;
219 present_parameters.Windowed = windowed;
220 present_parameters.hDeviceWindow = device_window;
221 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
222 present_parameters.BackBufferWidth = 640;
223 present_parameters.BackBufferHeight = 480;
224 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
225 present_parameters.EnableAutoDepthStencil = TRUE;
226 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
228 if (SUCCEEDED(IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
229 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device)))
230 return device;
232 return NULL;
235 static void cleanup_device(IDirect3DDevice9 *device)
237 if (device)
239 D3DPRESENT_PARAMETERS present_parameters;
240 IDirect3DSwapChain9 *swapchain;
241 ULONG ref;
243 IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
244 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
245 IDirect3DSwapChain9_Release(swapchain);
246 ref = IDirect3DDevice9_Release(device);
247 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
248 DestroyWindow(present_parameters.hDeviceWindow);
252 static void test_sanity(void)
254 IDirect3DDevice9 *device;
255 IDirect3D9 *d3d;
256 D3DCOLOR color;
257 ULONG refcount;
258 HWND window;
259 HRESULT hr;
261 window = create_window();
262 d3d = Direct3DCreate9(D3D_SDK_VERSION);
263 ok(!!d3d, "Failed to create a D3D object.\n");
264 if (!(device = create_device(d3d, window, window, TRUE)))
266 skip("Failed to create a D3D device, skipping tests.\n");
267 goto done;
270 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
271 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
272 color = getPixelColor(device, 1, 1);
273 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
275 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
276 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
278 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
279 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
280 color = getPixelColor(device, 639, 479);
281 ok(color == 0x0000ddee, "Got unexpected color 0x%08x.\n", color);
283 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
284 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
286 refcount = IDirect3DDevice9_Release(device);
287 ok(!refcount, "Device has %u references left.\n", refcount);
288 done:
289 IDirect3D9_Release(d3d);
290 DestroyWindow(window);
293 static void lighting_test(void)
295 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
296 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
297 IDirect3DDevice9 *device;
298 D3DMATERIAL9 material;
299 IDirect3D9 *d3d;
300 D3DCOLOR color;
301 ULONG refcount;
302 HWND window;
303 HRESULT hr;
304 unsigned int i;
306 static const D3DMATRIX mat =
308 1.0f, 0.0f, 0.0f, 0.0f,
309 0.0f, 1.0f, 0.0f, 0.0f,
310 0.0f, 0.0f, 1.0f, 0.0f,
311 0.0f, 0.0f, 0.0f, 1.0f,
312 }}},
313 mat_singular =
315 1.0f, 0.0f, 1.0f, 0.0f,
316 0.0f, 1.0f, 0.0f, 0.0f,
317 1.0f, 0.0f, 1.0f, 0.0f,
318 0.0f, 0.0f, 0.5f, 1.0f,
319 }}},
320 mat_transf =
322 0.0f, 0.0f, 1.0f, 0.0f,
323 0.0f, 1.0f, 0.0f, 0.0f,
324 -1.0f, 0.0f, 0.0f, 0.0f,
325 10.f, 10.0f, 10.0f, 1.0f,
326 }}},
327 mat_nonaffine =
329 1.0f, 0.0f, 0.0f, 0.0f,
330 0.0f, 1.0f, 0.0f, 0.0f,
331 0.0f, 0.0f, 1.0f, -1.0f,
332 10.f, 10.0f, 10.0f, 0.0f,
333 }}};
334 static const struct
336 struct vec3 position;
337 DWORD diffuse;
339 unlitquad[] =
341 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
342 {{-1.0f, 0.0f, 0.1f}, 0xffff0000},
343 {{ 0.0f, 0.0f, 0.1f}, 0xffff0000},
344 {{ 0.0f, -1.0f, 0.1f}, 0xffff0000},
346 litquad[] =
348 {{-1.0f, 0.0f, 0.1f}, 0xff00ff00},
349 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
350 {{ 0.0f, 1.0f, 0.1f}, 0xff00ff00},
351 {{ 0.0f, 0.0f, 0.1f}, 0xff00ff00},
353 lighting_test[] =
355 {{-1.0f, -1.0f, 0.1f}, 0x8000ff00},
356 {{ 1.0f, -1.0f, 0.1f}, 0x80000000},
357 {{-1.0f, 1.0f, 0.1f}, 0x8000ff00},
358 {{ 1.0f, 1.0f, 0.1f}, 0x80000000},
360 static const struct
362 struct vec3 position;
363 struct vec3 normal;
364 DWORD diffuse;
366 unlitnquad[] =
368 {{0.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
369 {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
370 {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
371 {{1.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
373 litnquad[] =
375 {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
376 {{0.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
377 {{1.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
378 {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
380 nquad[] =
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},
385 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
387 rotatedquad[] =
389 {{-10.0f, -11.0f, 11.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
390 {{-10.0f, -9.0f, 11.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
391 {{-10.0f, -9.0f, 9.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
392 {{-10.0f, -11.0f, 9.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
394 translatedquad[] =
396 {{-11.0f, -11.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
397 {{-11.0f, -9.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
398 {{ -9.0f, -9.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
399 {{ -9.0f, -11.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
401 static const WORD indices[] = {0, 1, 2, 2, 3, 0};
402 static const struct
404 const D3DMATRIX *world_matrix;
405 const void *quad;
406 unsigned int size;
407 DWORD expected;
408 const char *message;
410 tests[] =
412 {&mat, nquad, sizeof(nquad[0]), 0x000000ff, "Lit quad with light"},
413 {&mat_singular, nquad, sizeof(nquad[0]), 0x000000ff, "Lit quad with singular world matrix"},
414 {&mat_transf, rotatedquad, sizeof(rotatedquad[0]), 0x000000ff, "Lit quad with transformation matrix"},
415 {&mat_nonaffine, translatedquad, sizeof(translatedquad[0]), 0x00000000, "Lit quad with non-affine matrix"},
418 window = create_window();
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 point_side =
640 D3DLIGHT_POINT,
641 {0.0f, 0.0f, 0.0f, 0.0f},
642 {1.0f, 1.0f, 1.0f, 0.0f},
643 {0.0f, 0.0f, 0.0f, 0.0f},
644 {-1.1f, 0.0f, 1.1f},
645 {0.0f, 0.0f, 0.0f},
646 100.0f,
647 0.0f,
648 0.0f, 0.0f, 1.0f,
650 static const struct expected_color
652 unsigned int x, y;
653 D3DCOLOR color;
655 expected_directional[] =
657 {160, 120, 0x00ffffff},
658 {320, 120, 0x00ffffff},
659 {480, 120, 0x00ffffff},
660 {160, 240, 0x00ffffff},
661 {320, 240, 0x00ffffff},
662 {480, 240, 0x00ffffff},
663 {160, 360, 0x00ffffff},
664 {320, 360, 0x00ffffff},
665 {480, 360, 0x00ffffff},
667 expected_directional_local[] =
669 {160, 120, 0x003c3c3c},
670 {320, 120, 0x00717171},
671 {480, 120, 0x003c3c3c},
672 {160, 240, 0x00717171},
673 {320, 240, 0x00ffffff},
674 {480, 240, 0x00717171},
675 {160, 360, 0x003c3c3c},
676 {320, 360, 0x00717171},
677 {480, 360, 0x003c3c3c},
679 expected_point[] =
681 {160, 120, 0x00282828},
682 {320, 120, 0x005a5a5a},
683 {480, 120, 0x00282828},
684 {160, 240, 0x005a5a5a},
685 {320, 240, 0x00ffffff},
686 {480, 240, 0x005a5a5a},
687 {160, 360, 0x00282828},
688 {320, 360, 0x005a5a5a},
689 {480, 360, 0x00282828},
691 expected_point_local[] =
693 {160, 120, 0x00000000},
694 {320, 120, 0x00070707},
695 {480, 120, 0x00000000},
696 {160, 240, 0x00070707},
697 {320, 240, 0x00ffffff},
698 {480, 240, 0x00070707},
699 {160, 360, 0x00000000},
700 {320, 360, 0x00070707},
701 {480, 360, 0x00000000},
703 expected_spot[] =
705 {160, 120, 0x00000000},
706 {320, 120, 0x00141414},
707 {480, 120, 0x00000000},
708 {160, 240, 0x00141414},
709 {320, 240, 0x00ffffff},
710 {480, 240, 0x00141414},
711 {160, 360, 0x00000000},
712 {320, 360, 0x00141414},
713 {480, 360, 0x00000000},
715 expected_spot_local[] =
717 {160, 120, 0x00000000},
718 {320, 120, 0x00020202},
719 {480, 120, 0x00000000},
720 {160, 240, 0x00020202},
721 {320, 240, 0x00ffffff},
722 {480, 240, 0x00020202},
723 {160, 360, 0x00000000},
724 {320, 360, 0x00020202},
725 {480, 360, 0x00000000},
727 expected_point_range[] =
729 {160, 120, 0x00000000},
730 {320, 120, 0x005a5a5a},
731 {480, 120, 0x00000000},
732 {160, 240, 0x005a5a5a},
733 {320, 240, 0x00ffffff},
734 {480, 240, 0x005a5a5a},
735 {160, 360, 0x00000000},
736 {320, 360, 0x005a5a5a},
737 {480, 360, 0x00000000},
739 expected_point_side[] =
741 {160, 120, 0x00000000},
742 {320, 120, 0x00000000},
743 {480, 120, 0x00000000},
744 {160, 240, 0x00000000},
745 {320, 240, 0x00000000},
746 {480, 240, 0x00000000},
747 {160, 360, 0x00000000},
748 {320, 360, 0x00000000},
749 {480, 360, 0x00000000},
751 static const struct
753 const D3DLIGHT9 *light;
754 BOOL local_viewer;
755 float specular_power;
756 const struct expected_color *expected;
757 unsigned int expected_count;
759 tests[] =
761 {&directional, FALSE, 30.0f, expected_directional,
762 sizeof(expected_directional) / sizeof(expected_directional[0])},
763 {&directional, TRUE, 30.0f, expected_directional_local,
764 sizeof(expected_directional_local) / sizeof(expected_directional_local[0])},
765 {&point, FALSE, 30.0f, expected_point,
766 sizeof(expected_point) / sizeof(expected_point[0])},
767 {&point, TRUE, 30.0f, expected_point_local,
768 sizeof(expected_point_local) / sizeof(expected_point_local[0])},
769 {&spot, FALSE, 30.0f, expected_spot,
770 sizeof(expected_spot) / sizeof(expected_spot[0])},
771 {&spot, TRUE, 30.0f, expected_spot_local,
772 sizeof(expected_spot_local) / sizeof(expected_spot_local[0])},
773 {&point_range, FALSE, 30.0f, expected_point_range,
774 sizeof(expected_point_range) / sizeof(expected_point_range[0])},
775 {&point_side, TRUE, 0.0f, expected_point_side,
776 sizeof(expected_point_side) / sizeof(expected_point_side[0])},
778 IDirect3DDevice9 *device;
779 D3DMATERIAL9 material;
780 IDirect3D9 *d3d;
781 D3DCOLOR color;
782 ULONG refcount;
783 HWND window;
784 HRESULT hr;
785 unsigned int i, j, x, y;
786 struct
788 struct vec3 position;
789 struct vec3 normal;
790 } *quad;
791 WORD *indices;
793 quad = HeapAlloc(GetProcessHeap(), 0, vertices_side * vertices_side * sizeof(*quad));
794 indices = HeapAlloc(GetProcessHeap(), 0, indices_count * sizeof(*indices));
795 for (i = 0, y = 0; y < vertices_side; ++y)
797 for (x = 0; x < vertices_side; ++x)
799 quad[i].position.x = x * 2.0f / (vertices_side - 1) - 1.0f;
800 quad[i].position.y = y * 2.0f / (vertices_side - 1) - 1.0f;
801 quad[i].position.z = 1.0f;
802 quad[i].normal.x = 0.0f;
803 quad[i].normal.y = 0.0f;
804 quad[i++].normal.z = -1.0f;
807 for (i = 0, y = 0; y < (vertices_side - 1); ++y)
809 for (x = 0; x < (vertices_side - 1); ++x)
811 indices[i++] = y * vertices_side + x + 1;
812 indices[i++] = y * vertices_side + x;
813 indices[i++] = (y + 1) * vertices_side + x;
814 indices[i++] = y * vertices_side + x + 1;
815 indices[i++] = (y + 1) * vertices_side + x;
816 indices[i++] = (y + 1) * vertices_side + x + 1;
820 window = create_window();
821 d3d = Direct3DCreate9(D3D_SDK_VERSION);
822 ok(!!d3d, "Failed to create a D3D object.\n");
823 if (!(device = create_device(d3d, window, window, TRUE)))
825 skip("Failed to create a D3D device, skipping tests.\n");
826 goto done;
829 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
830 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
831 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
832 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
833 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
834 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
835 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
836 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
837 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
838 ok(SUCCEEDED(hr), "Failed to disable z test, hr %#x.\n", hr);
839 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
840 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
842 hr = IDirect3DDevice9_SetFVF(device, fvf);
843 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
845 hr = IDirect3DDevice9_LightEnable(device, 0, TRUE);
846 ok(SUCCEEDED(hr), "Failed to enable light 0, hr %#x.\n", hr);
847 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
848 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#x.\n", hr);
850 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
852 hr = IDirect3DDevice9_SetLight(device, 0, tests[i].light);
853 ok(SUCCEEDED(hr), "Failed to set light parameters, hr %#x.\n", hr);
855 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LOCALVIEWER, tests[i].local_viewer);
856 ok(SUCCEEDED(hr), "Failed to set local viewer state, hr %#x.\n", hr);
858 memset(&material, 0, sizeof(material));
859 material.Specular.r = 1.0f;
860 material.Specular.g = 1.0f;
861 material.Specular.b = 1.0f;
862 material.Specular.a = 1.0f;
863 material.Power = tests[i].specular_power;
864 hr = IDirect3DDevice9_SetMaterial(device, &material);
865 ok(SUCCEEDED(hr), "Failed to set material, hr %#x.\n", hr);
867 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
868 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
870 hr = IDirect3DDevice9_BeginScene(device);
871 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
873 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST,
874 0, vertices_side * vertices_side, indices_count / 3, indices,
875 D3DFMT_INDEX16, quad, sizeof(quad[0]));
876 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
878 hr = IDirect3DDevice9_EndScene(device);
879 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
881 for (j = 0; j < tests[i].expected_count; ++j)
883 color = getPixelColor(device, tests[i].expected[j].x, tests[i].expected[j].y);
884 ok(color_match(color, tests[i].expected[j].color, 1),
885 "Expected color 0x%08x at location (%u, %u), got 0x%08x, case %u.\n",
886 tests[i].expected[j].color, tests[i].expected[j].x,
887 tests[i].expected[j].y, color, i);
891 refcount = IDirect3DDevice9_Release(device);
892 ok(!refcount, "Device has %u references left.\n", refcount);
893 done:
894 IDirect3D9_Release(d3d);
895 DestroyWindow(window);
896 HeapFree(GetProcessHeap(), 0, indices);
897 HeapFree(GetProcessHeap(), 0, quad);
900 static void clear_test(void)
902 static const D3DMATRIX mat =
904 1.0f, 0.0f, 0.0f, 0.0f,
905 0.0f, 1.0f, 0.0f, 0.0f,
906 0.0f, 0.0f, 1.0f, 0.0f,
907 0.0f, 0.0f, 0.0f, 1.0f,
908 }}};
909 static const struct
911 struct vec3 position;
912 DWORD diffuse;
914 quad[] =
916 {{-1.0f, -1.0f, 0.1f}, 0xff7f7f7f},
917 {{ 1.0f, -1.0f, 0.1f}, 0xff7f7f7f},
918 {{-1.0f, 1.0f, 0.1f}, 0xff7f7f7f},
919 {{ 1.0f, 1.0f, 0.1f}, 0xff7f7f7f},
921 IDirect3DSurface9 *surface0, *surface1, *backbuffer;
922 IDirect3DTexture9 *texture;
923 HRESULT hr;
924 D3DRECT rect[2];
925 D3DRECT rect_negneg;
926 DWORD color;
927 D3DVIEWPORT9 old_vp, vp;
928 RECT scissor;
929 DWORD oldColorWrite;
930 BOOL invalid_clear_failed = FALSE, srgb_supported;
931 IDirect3DDevice9 *device;
932 IDirect3D9 *d3d;
933 ULONG refcount;
934 HWND window;
936 window = create_window();
937 d3d = Direct3DCreate9(D3D_SDK_VERSION);
938 ok(!!d3d, "Failed to create a D3D object.\n");
939 if (!(device = create_device(d3d, window, window, TRUE)))
941 skip("Failed to create a D3D device, skipping tests.\n");
942 goto done;
945 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
946 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
948 /* Positive x, negative y */
949 rect[0].x1 = 0;
950 rect[0].y1 = 480;
951 rect[0].x2 = 320;
952 rect[0].y2 = 240;
954 /* Positive x, positive y */
955 rect[1].x1 = 0;
956 rect[1].y1 = 0;
957 rect[1].x2 = 320;
958 rect[1].y2 = 240;
959 /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
960 * returns D3D_OK, but ignores the rectangle silently
962 hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
963 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
964 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
966 /* negative x, negative y */
967 rect_negneg.x1 = 640;
968 rect_negneg.y1 = 240;
969 rect_negneg.x2 = 320;
970 rect_negneg.y2 = 0;
971 hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
972 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
973 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
975 color = getPixelColor(device, 160, 360); /* lower left quad */
976 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
977 color = getPixelColor(device, 160, 120); /* upper left quad */
978 if(invalid_clear_failed) {
979 /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
980 ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
981 } else {
982 /* If the negative rectangle was dropped silently, the correct ones are cleared */
983 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
985 color = getPixelColor(device, 480, 360); /* lower right quad */
986 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
987 color = getPixelColor(device, 480, 120); /* upper right quad */
988 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
990 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
992 /* Hack to work around a nvidia windows driver bug. The clear below is supposed to
993 * clear the red quad in the top left part of the render target. For some reason it
994 * doesn't work if the clear color is 0xffffffff on some versions of the Nvidia Windows
995 * driver(tested on 8.17.12.5896, Win7). A clear with a different color works around
996 * this bug and fixes the clear with the white color. Even 0xfeffffff works, but let's
997 * pick some obvious value
999 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbabe, 0.0, 0);
1000 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1002 /* Test how the viewport affects clears */
1003 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1004 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1005 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
1006 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
1008 vp.X = 160;
1009 vp.Y = 120;
1010 vp.Width = 160;
1011 vp.Height = 120;
1012 vp.MinZ = 0.0;
1013 vp.MaxZ = 1.0;
1014 hr = IDirect3DDevice9_SetViewport(device, &vp);
1015 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
1016 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1017 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1019 vp.X = 320;
1020 vp.Y = 240;
1021 vp.Width = 320;
1022 vp.Height = 240;
1023 vp.MinZ = 0.0;
1024 vp.MaxZ = 1.0;
1025 hr = IDirect3DDevice9_SetViewport(device, &vp);
1026 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
1027 rect[0].x1 = 160;
1028 rect[0].y1 = 120;
1029 rect[0].x2 = 480;
1030 rect[0].y2 = 360;
1031 hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1032 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1034 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
1035 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
1037 color = getPixelColor(device, 158, 118);
1038 ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
1039 color = getPixelColor(device, 162, 118);
1040 ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
1041 color = getPixelColor(device, 158, 122);
1042 ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
1043 color = getPixelColor(device, 162, 122);
1044 ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
1046 color = getPixelColor(device, 318, 238);
1047 ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
1048 color = getPixelColor(device, 322, 238);
1049 ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
1050 color = getPixelColor(device, 318, 242);
1051 ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
1052 color = getPixelColor(device, 322, 242);
1053 ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
1055 color = getPixelColor(device, 478, 358);
1056 ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
1057 color = getPixelColor(device, 482, 358);
1058 ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
1059 color = getPixelColor(device, 478, 362);
1060 ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
1061 color = getPixelColor(device, 482, 362);
1062 ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
1064 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1066 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1067 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1069 SetRect(&scissor, 160, 120, 480, 360);
1070 hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
1071 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
1072 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
1073 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
1075 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1076 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1077 hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1078 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1080 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
1081 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
1083 color = getPixelColor(device, 158, 118);
1084 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
1085 color = getPixelColor(device, 162, 118);
1086 ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
1087 color = getPixelColor(device, 158, 122);
1088 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
1089 color = getPixelColor(device, 162, 122);
1090 ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
1092 color = getPixelColor(device, 158, 358);
1093 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
1094 color = getPixelColor(device, 162, 358);
1095 ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
1096 color = getPixelColor(device, 158, 358);
1097 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
1098 color = getPixelColor(device, 162, 362);
1099 ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
1101 color = getPixelColor(device, 478, 118);
1102 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
1103 color = getPixelColor(device, 478, 122);
1104 ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
1105 color = getPixelColor(device, 482, 122);
1106 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
1107 color = getPixelColor(device, 482, 358);
1108 ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
1110 color = getPixelColor(device, 478, 358);
1111 ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
1112 color = getPixelColor(device, 478, 362);
1113 ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
1114 color = getPixelColor(device, 482, 358);
1115 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
1116 color = getPixelColor(device, 482, 362);
1117 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
1119 color = getPixelColor(device, 318, 238);
1120 ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
1121 color = getPixelColor(device, 318, 242);
1122 ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
1123 color = getPixelColor(device, 322, 238);
1124 ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
1125 color = getPixelColor(device, 322, 242);
1126 ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
1128 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1130 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
1131 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1132 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
1133 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
1135 /* Same nvidia windows driver trouble with white clears as earlier in the same test */
1136 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbeef, 0.0, 0);
1137 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1139 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1140 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1142 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
1143 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
1145 /* Colorwriteenable does not affect the clear */
1146 color = getPixelColor(device, 320, 240);
1147 ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
1149 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1151 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
1152 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1154 rect[0].x1 = 0;
1155 rect[0].y1 = 0;
1156 rect[0].x2 = 640;
1157 rect[0].y2 = 480;
1158 hr = IDirect3DDevice9_Clear(device, 0, rect, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
1159 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1161 color = getPixelColor(device, 320, 240);
1162 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), 1),
1163 "Clear with count = 0, rect != NULL has color %08x\n", color);
1165 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1167 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1168 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1169 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1170 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1172 color = getPixelColor(device, 320, 240);
1173 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1174 "Clear with count = 1, rect = NULL has color %08x\n", color);
1176 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1178 /* Test D3DRS_SRGBWRITEENABLE interactions with clears. */
1179 srgb_supported = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
1180 D3DUSAGE_QUERY_SRGBWRITE, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8));
1181 trace("sRGB writing to D3DFMT_A8R8G8B8 is %ssupported.\n", srgb_supported ? "" : "not ");
1182 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1183 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
1185 color = getPixelColor(device, 320, 240);
1186 ok(color_match(color, 0x007f7f7f, 1), "Clear has color %08x.\n", color);
1188 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
1189 ok(SUCCEEDED(hr), "Failed to enable sRGB write, hr %#x.\n", hr);
1191 /* Draw something to make sure the SRGBWRITEENABLE setting is applied. */
1192 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
1193 ok(SUCCEEDED(hr), "Failed to set world matrix, hr %#x.\n", hr);
1194 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
1195 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
1196 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
1197 ok(SUCCEEDED(hr), "Failed to disable z test, hr %#x.\n", hr);
1198 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1199 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
1200 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
1201 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#x.\n", hr);
1202 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
1203 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
1204 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1205 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
1206 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1207 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1208 hr = IDirect3DDevice9_BeginScene(device);
1209 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1210 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad));
1211 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1212 hr = IDirect3DDevice9_EndScene(device);
1213 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1215 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1216 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
1218 color = getPixelColor(device, 320, 240);
1219 ok(color_match(color, 0x00bbbbbb, 1), "Clear has color %08x.\n", color);
1221 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
1222 ok(SUCCEEDED(hr), "Failed to disable sRGB write, hr %#x.\n", hr);
1224 /* Switching to a new render target seems to be enough to make Windows pick
1225 * up on the changed render state. */
1226 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 2, D3DUSAGE_RENDERTARGET,
1227 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
1228 ok(SUCCEEDED(hr), "Failed to create the offscreen render target, hr %#x.\n", hr);
1229 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1230 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
1231 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface0);
1232 ok(SUCCEEDED(hr), "Failed to get offscreen surface, hr %#x.\n", hr);
1233 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface0);
1234 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1236 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1237 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
1239 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1240 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1242 hr = IDirect3DDevice9_StretchRect(device, surface0, NULL, backbuffer, NULL, D3DTEXF_NONE);
1243 ok(SUCCEEDED(hr), "Failed to blit surface, hr %#x.\n", hr);
1245 color = getPixelColor(device, 64, 64);
1246 ok(color_match(color, 0x007f7f7f, 1), "Clear has color %08x.\n", color);
1248 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
1249 ok(SUCCEEDED(hr), "Failed to enable sRGB write, hr %#x.\n", hr);
1251 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface0);
1252 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1254 hr = IDirect3DDevice9_BeginScene(device);
1255 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1256 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad));
1257 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1258 hr = IDirect3DDevice9_EndScene(device);
1259 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1261 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1262 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
1264 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1265 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1267 hr = IDirect3DDevice9_StretchRect(device, surface0, NULL, backbuffer, NULL, D3DTEXF_NONE);
1268 ok(SUCCEEDED(hr), "Failed to blit surface, hr %#x.\n", hr);
1270 color = getPixelColor(device, 320, 240);
1271 ok(color_match(color, 0x00bbbbbb, 1), "Clear has color %08x.\n", color);
1273 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
1274 ok(SUCCEEDED(hr), "Failed to disable sRGB write, hr %#x.\n", hr);
1275 /* Switching to another surface of the same texture is also enough to make
1276 * the setting "stick". */
1277 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface1);
1278 ok(SUCCEEDED(hr), "Failed to get offscreen surface, hr %#x.\n", hr);
1279 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface1);
1280 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1282 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1283 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
1285 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1286 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1288 hr = IDirect3DDevice9_StretchRect(device, surface1, NULL, backbuffer, NULL, D3DTEXF_NONE);
1289 ok(SUCCEEDED(hr), "Failed to blit surface, hr %#x.\n", hr);
1291 color = getPixelColor(device, 320, 240);
1292 ok(color_match(color, 0x007f7f7f, 1), "Clear has color %08x.\n", color);
1294 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1296 IDirect3DSurface9_Release(surface1);
1297 IDirect3DSurface9_Release(surface0);
1298 IDirect3DSurface9_Release(backbuffer);
1299 IDirect3DTexture9_Release(texture);
1300 refcount = IDirect3DDevice9_Release(device);
1301 ok(!refcount, "Device has %u references left.\n", refcount);
1302 done:
1303 IDirect3D9_Release(d3d);
1304 DestroyWindow(window);
1307 static void color_fill_test(void)
1309 IDirect3DSurface9 *surface;
1310 IDirect3DTexture9 *texture;
1311 D3DCOLOR fill_color, color;
1312 DWORD fill_a, expected_a;
1313 IDirect3DDevice9 *device;
1314 IDirect3D9 *d3d;
1315 ULONG refcount;
1316 HWND window;
1317 HRESULT hr;
1318 static const struct
1320 D3DPOOL pool;
1321 DWORD usage;
1322 HRESULT hr;
1324 resource_types[] =
1326 {D3DPOOL_DEFAULT, 0, D3DERR_INVALIDCALL},
1327 {D3DPOOL_DEFAULT, D3DUSAGE_DYNAMIC, D3DERR_INVALIDCALL},
1328 {D3DPOOL_DEFAULT, D3DUSAGE_RENDERTARGET, D3D_OK},
1329 {D3DPOOL_SYSTEMMEM, 0, D3DERR_INVALIDCALL},
1330 {D3DPOOL_MANAGED, 0, D3DERR_INVALIDCALL},
1331 {D3DPOOL_SCRATCH, 0, D3DERR_INVALIDCALL},
1333 static const struct
1335 D3DFORMAT format;
1336 const char *name;
1337 enum
1339 CHECK_FILL_VALUE = 0x1,
1340 BLOCKS = 0x2,
1341 } flags;
1342 DWORD fill_value;
1344 formats[] =
1346 {D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8", CHECK_FILL_VALUE, 0xdeadbeef},
1347 /* D3DFMT_X8R8G8B8 either set X = A or X = 0, depending on the driver. */
1348 {D3DFMT_R5G6B5, "D3DFMT_R5G6B5", CHECK_FILL_VALUE, 0xadfdadfd},
1349 {D3DFMT_G16R16, "D3DFMT_G16R16", CHECK_FILL_VALUE, 0xbebeadad},
1350 /* Real hardware reliably fills the surface with the blue channel but
1351 * the testbot fills it with 0x00. Wine incorrectly uses the alpha
1352 * channel. Don't bother checking the result because P8 surfaces are
1353 * essentially useless in d3d9. */
1354 {D3DFMT_P8, "D3DFMT_P8", 0, 0xefefefef},
1355 /* Windows drivers produce different results for these formats.
1356 * No driver produces a YUV value that matches the input RGB
1357 * value, and no driver produces a proper DXT compression block.
1359 * Even the clear value 0 does not reliably produce a fill value
1360 * that will return vec4(0.0, 0.0, 0.0, 0.0) when sampled.
1362 * The YUV tests are disabled because they produce a driver-dependent
1363 * result on Wine.
1364 * {D3DFMT_YUY2, "D3DFMT_YUY2", BLOCKS, 0},
1365 * {D3DFMT_UYVY, "D3DFMT_UYVY", BLOCKS, 0}, */
1366 {D3DFMT_DXT1, "D3DFMT_DXT1", BLOCKS, 0x00000000},
1367 /* Vendor-specific formats like ATI2N are a non-issue here since they're not
1368 * supported as offscreen plain surfaces and do not support D3DUSAGE_RENDERTARGET
1369 * when created as texture. */
1371 unsigned int i;
1372 D3DLOCKED_RECT locked_rect;
1373 DWORD *surface_data;
1374 static const RECT rect = {4, 4, 8, 8}, rect2 = {5, 5, 7, 7};
1376 window = create_window();
1377 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1378 ok(!!d3d, "Failed to create a D3D object.\n");
1379 if (!(device = create_device(d3d, window, window, TRUE)))
1381 skip("Failed to create a D3D device, skipping tests.\n");
1382 goto done;
1385 /* Test ColorFill on a the backbuffer (should pass) */
1386 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &surface);
1387 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1389 fill_color = 0x112233;
1390 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1391 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
1393 color = getPixelColor(device, 0, 0);
1394 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
1396 IDirect3DSurface9_Release(surface);
1398 /* Test ColorFill on a render target surface (should pass) */
1399 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8,
1400 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL );
1401 ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
1403 fill_color = 0x445566;
1404 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1405 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
1407 color = getPixelColorFromSurface(surface, 0, 0);
1408 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
1410 IDirect3DSurface9_Release(surface);
1412 /* Test ColorFill on an offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
1413 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1414 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surface, NULL);
1415 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
1417 fill_color = 0x778899;
1418 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1419 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
1421 color = getPixelColorFromSurface(surface, 0, 0);
1422 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
1424 IDirect3DSurface9_Release(surface);
1426 /* Try ColorFill on an offscreen surface in sysmem (should fail) */
1427 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1428 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1429 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
1431 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, 0);
1432 ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
1434 IDirect3DSurface9_Release(surface);
1436 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D16,
1437 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
1438 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr = %08x.\n", hr);
1440 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, 0);
1441 ok(hr == D3DERR_INVALIDCALL, "ColorFill on a depth stencil surface returned hr = %08x.\n", hr);
1443 IDirect3DSurface9_Release(surface);
1445 for (i = 0; i < sizeof(resource_types) / sizeof(resource_types[0]); i++)
1447 texture = NULL;
1448 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, resource_types[i].usage,
1449 D3DFMT_A8R8G8B8, resource_types[i].pool, &texture, NULL);
1450 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, i=%u.\n", hr, i);
1451 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1452 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x, i=%u.\n", hr, i);
1454 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1455 ok(hr == resource_types[i].hr, "Got unexpected hr %#x, expected %#x, i=%u.\n",
1456 hr, resource_types[i].hr, i);
1458 IDirect3DSurface9_Release(surface);
1459 IDirect3DTexture9_Release(texture);
1462 for (i = 0; i < sizeof(formats) / sizeof(formats[0]); i++)
1464 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
1465 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, formats[i].format) != D3D_OK)
1467 skip("Offscreenplain %s surfaces not supported, skipping colorfill test\n", formats[i].name);
1468 continue;
1471 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1472 formats[i].format, D3DPOOL_DEFAULT, &surface, NULL);
1473 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x, fmt=%s.\n", hr, formats[i].name);
1475 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, 0xdeadbeef);
1476 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x, fmt=%s.\n", hr, formats[i].name);
1478 hr = IDirect3DDevice9_ColorFill(device, surface, &rect, 0xdeadbeef);
1479 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x, fmt=%s.\n", hr, formats[i].name);
1481 if (SUCCEEDED(hr))
1483 hr = IDirect3DDevice9_ColorFill(device, surface, &rect2, 0xdeadbeef);
1484 if (formats[i].flags & BLOCKS)
1485 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, fmt=%s.\n", hr, formats[i].name);
1486 else
1487 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x, fmt=%s.\n", hr, formats[i].name);
1490 if (formats[i].flags & CHECK_FILL_VALUE)
1492 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, D3DLOCK_READONLY);
1493 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x, fmt=%s.\n", hr, formats[i].name);
1494 surface_data = locked_rect.pBits;
1495 fill_a = (surface_data[0] & 0xff000000) >> 24;
1496 expected_a = (formats[i].fill_value & 0xff000000) >> 24;
1497 /* Windows drivers disagree on how to promote the 8 bit per channel
1498 * input argument to 16 bit for D3DFMT_G16R16. */
1499 ok(color_match(surface_data[0], formats[i].fill_value, 2) &&
1500 abs((expected_a) - (fill_a)) < 3,
1501 "Expected clear value 0x%08x, got 0x%08x, fmt=%s.\n",
1502 formats[i].fill_value, surface_data[0], formats[i].name);
1503 hr = IDirect3DSurface9_UnlockRect(surface);
1504 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, fmt=%s.\n", hr, formats[i].name);
1507 IDirect3DSurface9_Release(surface);
1510 refcount = IDirect3DDevice9_Release(device);
1511 ok(!refcount, "Device has %u references left.\n", refcount);
1512 done:
1513 IDirect3D9_Release(d3d);
1514 DestroyWindow(window);
1518 * c7 mova ARGB mov ARGB
1519 * -2.4 -2 0x00ffff00 -3 0x00ff0000
1520 * -1.6 -2 0x00ffff00 -2 0x00ffff00
1521 * -0.4 0 0x0000ffff -1 0x0000ff00
1522 * 0.4 0 0x0000ffff 0 0x0000ffff
1523 * 1.6 2 0x00ff00ff 1 0x000000ff
1524 * 2.4 2 0x00ff00ff 2 0x00ff00ff
1526 static void test_mova(void)
1528 IDirect3DVertexDeclaration9 *vertex_declaration;
1529 IDirect3DVertexShader9 *mova_shader;
1530 IDirect3DVertexShader9 *mov_shader;
1531 IDirect3DDevice9 *device;
1532 unsigned int i, j;
1533 IDirect3D9 *d3d;
1534 ULONG refcount;
1535 D3DCAPS9 caps;
1536 HWND window;
1537 HRESULT hr;
1539 static const DWORD mova_test[] =
1541 0xfffe0200, /* vs_2_0 */
1542 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1543 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
1544 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
1545 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
1546 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
1547 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
1548 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
1549 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
1550 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
1551 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
1552 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1553 0x0000ffff /* END */
1555 static const DWORD mov_test[] =
1557 0xfffe0101, /* vs_1_1 */
1558 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1559 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
1560 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
1561 0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
1562 0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
1563 0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
1564 0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
1565 0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
1566 0x00000001, 0xb0010000, 0xa0000007, /* mov a0.x, c7.x */
1567 0x00000001, 0xd00f0000, 0xa0e42003, /* mov oD0, c[a0.x + 3] */
1568 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1569 0x0000ffff /* END */
1571 static const struct
1573 float in[4];
1574 DWORD out;
1576 test_data[2][6] =
1579 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
1580 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
1581 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
1582 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
1583 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
1584 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
1587 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
1588 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
1589 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
1590 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
1591 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
1592 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
1595 static const struct vec3 quad[] =
1597 {-1.0f, -1.0f, 0.0f},
1598 {-1.0f, 1.0f, 0.0f},
1599 { 1.0f, -1.0f, 0.0f},
1600 { 1.0f, 1.0f, 0.0f},
1602 static const D3DVERTEXELEMENT9 decl_elements[] =
1604 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1605 D3DDECL_END()
1608 window = create_window();
1609 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1610 ok(!!d3d, "Failed to create a D3D object.\n");
1611 if (!(device = create_device(d3d, window, window, TRUE)))
1613 skip("Failed to create a D3D device, skipping tests.\n");
1614 goto done;
1617 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1618 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1619 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
1621 skip("No vs_2_0 support, skipping tests.\n");
1622 IDirect3DDevice9_Release(device);
1623 goto done;
1626 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
1627 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1628 hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
1629 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1630 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1631 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1632 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1633 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1635 hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
1636 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1637 for (j = 0; j < sizeof(test_data) / sizeof(*test_data); ++j)
1639 for (i = 0; i < sizeof(*test_data) / sizeof(**test_data); ++i)
1641 DWORD color;
1643 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
1644 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
1646 hr = IDirect3DDevice9_BeginScene(device);
1647 ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
1649 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
1650 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1652 hr = IDirect3DDevice9_EndScene(device);
1653 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
1655 color = getPixelColor(device, 320, 240);
1656 ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
1657 test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
1659 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1660 ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
1662 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1663 ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
1665 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
1666 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1669 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1670 IDirect3DVertexShader9_Release(mova_shader);
1671 IDirect3DVertexShader9_Release(mov_shader);
1672 refcount = IDirect3DDevice9_Release(device);
1673 ok(!refcount, "Device has %u references left.\n", refcount);
1674 done:
1675 IDirect3D9_Release(d3d);
1676 DestroyWindow(window);
1679 static void fog_test(void)
1681 float start = 0.0f, end = 1.0f;
1682 IDirect3DDevice9 *device;
1683 IDirect3D9 *d3d;
1684 D3DCOLOR color;
1685 ULONG refcount;
1686 D3DCAPS9 caps;
1687 HWND window;
1688 HRESULT hr;
1689 int i;
1691 /* Gets full z based fog with linear fog, no fog with specular color. */
1692 static const struct
1694 float x, y, z;
1695 D3DCOLOR diffuse;
1696 D3DCOLOR specular;
1698 untransformed_1[] =
1700 {-1.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
1701 {-1.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
1702 { 0.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
1703 { 0.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
1705 /* Ok, I am too lazy to deal with transform matrices. */
1706 untransformed_2[] =
1708 {-1.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
1709 {-1.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
1710 { 0.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
1711 { 0.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
1713 untransformed_3[] =
1715 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1716 {-1.0f, 1.0f, 0.5f, 0xffff0000, 0xff000000},
1717 { 1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1718 { 1.0f, 1.0f, 0.5f, 0xffff0000, 0xff000000},
1720 far_quad1[] =
1722 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1723 {-1.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
1724 { 0.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
1725 { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1727 far_quad2[] =
1729 {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1730 {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
1731 { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
1732 { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1734 /* Untransformed ones. Give them a different diffuse color to make the
1735 * test look nicer. It also makes making sure that they are drawn
1736 * correctly easier. */
1737 static const struct
1739 float x, y, z, rhw;
1740 D3DCOLOR diffuse;
1741 D3DCOLOR specular;
1743 transformed_1[] =
1745 {320.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1746 {640.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1747 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1748 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1750 transformed_2[] =
1752 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1753 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1754 {640.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1755 {320.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1757 static const struct
1759 struct vec3 position;
1760 DWORD diffuse;
1762 rev_fog_quads[] =
1764 {{-1.0f, -1.0f, 0.1f}, 0x000000ff},
1765 {{-1.0f, 0.0f, 0.1f}, 0x000000ff},
1766 {{ 0.0f, 0.0f, 0.1f}, 0x000000ff},
1767 {{ 0.0f, -1.0f, 0.1f}, 0x000000ff},
1769 {{ 0.0f, -1.0f, 0.9f}, 0x000000ff},
1770 {{ 0.0f, 0.0f, 0.9f}, 0x000000ff},
1771 {{ 1.0f, 0.0f, 0.9f}, 0x000000ff},
1772 {{ 1.0f, -1.0f, 0.9f}, 0x000000ff},
1774 {{ 0.0f, 0.0f, 0.4f}, 0x000000ff},
1775 {{ 0.0f, 1.0f, 0.4f}, 0x000000ff},
1776 {{ 1.0f, 1.0f, 0.4f}, 0x000000ff},
1777 {{ 1.0f, 0.0f, 0.4f}, 0x000000ff},
1779 {{-1.0f, 0.0f, 0.7f}, 0x000000ff},
1780 {{-1.0f, 1.0f, 0.7f}, 0x000000ff},
1781 {{ 0.0f, 1.0f, 0.7f}, 0x000000ff},
1782 {{ 0.0f, 0.0f, 0.7f}, 0x000000ff},
1784 static const D3DMATRIX ident_mat =
1786 1.0f, 0.0f, 0.0f, 0.0f,
1787 0.0f, 1.0f, 0.0f, 0.0f,
1788 0.0f, 0.0f, 1.0f, 0.0f,
1789 0.0f, 0.0f, 0.0f, 1.0f
1790 }}};
1791 static const D3DMATRIX world_mat1 =
1793 1.0f, 0.0f, 0.0f, 0.0f,
1794 0.0f, 1.0f, 0.0f, 0.0f,
1795 0.0f, 0.0f, 1.0f, 0.0f,
1796 0.0f, 0.0f, -0.5f, 1.0f
1797 }}};
1798 static const D3DMATRIX world_mat2 =
1800 1.0f, 0.0f, 0.0f, 0.0f,
1801 0.0f, 1.0f, 0.0f, 0.0f,
1802 0.0f, 0.0f, 1.0f, 0.0f,
1803 0.0f, 0.0f, 1.0f, 1.0f
1804 }}};
1805 static const D3DMATRIX proj_mat =
1807 1.0f, 0.0f, 0.0f, 0.0f,
1808 0.0f, 1.0f, 0.0f, 0.0f,
1809 0.0f, 0.0f, 1.0f, 0.0f,
1810 0.0f, 0.0f, -1.0f, 1.0f
1811 }}};
1812 static const WORD Indices[] = {0, 1, 2, 2, 3, 0};
1813 static const WORD Indices2[] =
1815 0, 1, 2, 2, 3, 0,
1816 4, 5, 6, 6, 7, 4,
1817 8, 9, 10, 10, 11, 8,
1818 12, 13, 14, 14, 15, 12,
1821 window = create_window();
1822 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1823 ok(!!d3d, "Failed to create a D3D object.\n");
1824 if (!(device = create_device(d3d, window, window, TRUE)))
1826 skip("Failed to create a D3D device, skipping tests.\n");
1827 goto done;
1830 memset(&caps, 0, sizeof(caps));
1831 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1832 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
1833 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1834 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1836 /* Setup initial states: No lighting, fog on, fog color */
1837 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
1838 ok(SUCCEEDED(hr), "Failed to disable D3DRS_ZENABLE, hr %#x.\n", hr);
1839 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1840 ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
1841 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1842 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
1843 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xff00ff00 /* A nice green */);
1844 ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
1845 /* Some of the tests seem to depend on the projection matrix explicitly
1846 * being set to an identity matrix, even though that's the default.
1847 * (AMD Radeon HD 6310, Windows 7) */
1848 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
1849 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
1851 /* First test: Both table fog and vertex fog off */
1852 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1853 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
1854 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1855 ok(hr == D3D_OK, "Turning off vertex fog returned %08x\n", hr);
1857 /* Start = 0, end = 1. Should be default, but set them */
1858 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1859 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1860 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1861 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1863 hr = IDirect3DDevice9_BeginScene(device);
1864 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1866 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1867 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1869 /* Untransformed, vertex fog = NONE, table fog = NONE:
1870 * Read the fog weighting from the specular color. */
1871 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1872 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1873 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1875 /* That makes it use the Z value */
1876 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1877 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex mode, hr %#x.\n", hr);
1878 /* Untransformed, vertex fog != none (or table fog != none):
1879 * Use the Z value as input into the equation. */
1880 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1881 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1882 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1884 /* transformed verts */
1885 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1886 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1887 /* Transformed, vertex fog != NONE, pixel fog == NONE:
1888 * Use specular color alpha component. */
1889 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1890 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_1, sizeof(transformed_1[0]));
1891 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1893 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1894 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog table mode, hr %#x.\n", hr);
1895 /* Transformed, table fog != none, vertex anything:
1896 * Use Z value as input to the fog equation. */
1897 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1898 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_2, sizeof(transformed_2[0]));
1899 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1901 hr = IDirect3DDevice9_EndScene(device);
1902 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1904 color = getPixelColor(device, 160, 360);
1905 ok(color == 0x00ff0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1906 color = getPixelColor(device, 160, 120);
1907 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
1908 color = getPixelColor(device, 480, 120);
1909 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1910 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1912 color = getPixelColor(device, 480, 360);
1913 ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
1915 else
1917 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1918 * The settings above result in no fogging with vertex fog
1920 color = getPixelColor(device, 480, 120);
1921 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1922 trace("Info: Table fog not supported by this device\n");
1924 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1926 /* Now test the special case fogstart == fogend */
1927 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1928 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1930 hr = IDirect3DDevice9_BeginScene(device);
1931 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1933 start = 512;
1934 end = 512;
1935 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
1936 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#x.\n", hr);
1937 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
1938 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#x.\n", hr);
1940 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1941 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1942 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1943 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex mode, hr %#x.\n", hr);
1944 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1945 ok(SUCCEEDED(hr), "Failed to set D3DFOG_NONE fog table mode, hr %#x.\n", hr);
1947 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512.
1948 * Would result in a completely fog-free primitive because start > zcoord,
1949 * but because start == end, the primitive is fully covered by fog. The
1950 * same happens to the 2nd untransformed quad with z = 1.0. The third
1951 * transformed quad remains unfogged because the fogcoords are read from
1952 * the specular color and has fixed fogstart and fogend. */
1953 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1954 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1955 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1956 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1957 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1958 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1960 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1961 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1962 /* Transformed, vertex fog != NONE, pixel fog == NONE:
1963 * Use specular color alpha component. */
1964 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1965 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_1, sizeof(transformed_1[0]));
1966 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1968 hr = IDirect3DDevice9_EndScene(device);
1969 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1971 color = getPixelColor(device, 160, 360);
1972 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1973 color = getPixelColor(device, 160, 120);
1974 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1975 color = getPixelColor(device, 480, 120);
1976 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1977 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1979 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1980 * but without shaders it seems to work everywhere
1982 end = 0.2;
1983 start = 0.8;
1984 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1985 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1986 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1987 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1988 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1989 ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1991 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1992 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1993 * so skip this for now
1995 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1996 const char *mode = (i ? "table" : "vertex");
1997 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1998 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1999 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
2000 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2001 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
2002 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2003 hr = IDirect3DDevice9_BeginScene(device);
2004 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2005 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 16 /* NumVerts */,
2006 8 /* PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads, sizeof(rev_fog_quads[0]));
2007 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2008 hr = IDirect3DDevice9_EndScene(device);
2009 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2011 color = getPixelColor(device, 160, 360);
2012 ok(color_match(color, 0x0000ff00, 1),
2013 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
2015 color = getPixelColor(device, 160, 120);
2016 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
2017 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
2019 color = getPixelColor(device, 480, 120);
2020 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
2021 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
2023 color = getPixelColor(device, 480, 360);
2024 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
2026 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2028 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
2029 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
2030 break;
2034 if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
2036 /* A simple fog + non-identity world matrix test */
2037 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat1);
2038 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %#08x\n", hr);
2040 start = 0.0;
2041 end = 1.0;
2042 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
2043 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
2044 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
2045 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
2046 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
2047 ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
2048 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
2049 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
2051 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2052 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %#08x\n", hr);
2054 hr = IDirect3DDevice9_BeginScene(device);
2055 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2057 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
2058 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
2060 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2061 2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
2062 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2063 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2064 2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
2065 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2067 hr = IDirect3DDevice9_EndScene(device);
2068 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2070 color = getPixelColor(device, 160, 360);
2071 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 4),
2072 "Unfogged quad has color %08x\n", color);
2073 color = getPixelColor(device, 160, 120);
2074 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2075 "Fogged out quad has color %08x\n", color);
2077 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2079 /* Test fog behavior with an orthogonal (but non-identity) projection matrix */
2080 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat2);
2081 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
2082 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &proj_mat);
2083 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
2085 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2086 ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
2088 hr = IDirect3DDevice9_BeginScene(device);
2089 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2091 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
2092 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
2094 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2095 2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
2096 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2097 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2098 2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
2099 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2101 hr = IDirect3DDevice9_EndScene(device);
2102 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2104 color = getPixelColor(device, 160, 360);
2105 ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
2106 color = getPixelColor(device, 160, 120);
2107 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2108 "Fogged out quad has color %08x\n", color);
2110 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2112 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &ident_mat);
2113 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
2114 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
2115 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
2117 else
2119 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
2122 /* Test RANGEFOG vs FOGTABLEMODE */
2123 if ((caps.RasterCaps & (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE)) ==
2124 (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE))
2126 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2127 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
2128 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
2129 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
2131 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, TRUE);
2132 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
2134 /* z=0.5, x = +/- 1.0, y = +/- 1.0. In case of z fog the fog coordinate is
2135 * 0.5. With range fog it is sqrt(x*x + y*y + z*z) = 1.5 for all vertices.
2136 * Note that the fog coordinate is interpolated linearly across the vertices,
2137 * so the different eye distance at the screen center should not matter. */
2138 start = 0.75f;
2139 end = 0.75001f;
2140 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
2141 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
2142 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
2143 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
2145 /* Table fog: Range fog is not used */
2146 hr = IDirect3DDevice9_BeginScene(device);
2147 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2149 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
2150 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog table mode, hr %#x.\n", hr);
2151 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
2152 untransformed_3, sizeof(*untransformed_3));
2153 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2155 hr = IDirect3DDevice9_EndScene(device);
2156 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2158 color = getPixelColor(device, 10, 10);
2159 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2160 color = getPixelColor(device, 630, 10);
2161 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2162 color = getPixelColor(device, 10, 470);
2163 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2164 color = getPixelColor(device, 630, 470);
2165 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2167 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2168 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
2170 /* Vertex fog: Rangefog is used */
2171 hr = IDirect3DDevice9_BeginScene(device);
2172 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2174 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
2175 ok(SUCCEEDED(hr), "Failed to set D3DFOG_NONE fog table mode, hr %#x.\n", hr);
2176 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
2177 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex mode, hr %#x.\n", hr);
2178 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
2179 untransformed_3, sizeof(*untransformed_3));
2180 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2182 hr = IDirect3DDevice9_EndScene(device);
2183 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2185 color = getPixelColor(device, 10, 10);
2186 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2187 "Rangefog with vertex fog returned color 0x%08x\n", color);
2188 color = getPixelColor(device, 630, 10);
2189 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2190 "Rangefog with vertex fog returned color 0x%08x\n", color);
2191 color = getPixelColor(device, 10, 470);
2192 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2193 "Rangefog with vertex fog returned color 0x%08x\n", color);
2194 color = getPixelColor(device, 630, 470);
2195 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2196 "Rangefog with vertex fog returned color 0x%08x\n", color);
2198 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2199 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
2201 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, FALSE);
2202 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
2204 else
2206 skip("Range fog or table fog not supported, skipping range fog tests\n");
2209 refcount = IDirect3DDevice9_Release(device);
2210 ok(!refcount, "Device has %u references left.\n", refcount);
2211 done:
2212 IDirect3D9_Release(d3d);
2213 DestroyWindow(window);
2216 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
2217 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
2218 * regardless of the actual addressing mode set. The way this test works is
2219 * that we sample in one of the corners of the cubemap with filtering enabled,
2220 * and check the interpolated color. There are essentially two reasonable
2221 * things an implementation can do: Either pick one of the faces and
2222 * interpolate the edge texel with itself (i.e., clamp within the face), or
2223 * interpolate between the edge texels of the three involved faces. It should
2224 * never involve the border color or the other side (texcoord wrapping) of a
2225 * face in the interpolation. */
2226 static void test_cube_wrap(void)
2228 IDirect3DVertexDeclaration9 *vertex_declaration;
2229 IDirect3DSurface9 *face_surface, *surface;
2230 IDirect3DCubeTexture9 *texture;
2231 D3DLOCKED_RECT locked_rect;
2232 IDirect3DDevice9 *device;
2233 unsigned int x, y, face;
2234 IDirect3D9 *d3d;
2235 ULONG refcount;
2236 D3DCAPS9 caps;
2237 HWND window;
2238 HRESULT hr;
2240 static const float quad[][6] =
2242 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2243 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2244 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2245 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2247 static const D3DVERTEXELEMENT9 decl_elements[] =
2249 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2250 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2251 D3DDECL_END()
2253 static const struct
2255 D3DTEXTUREADDRESS mode;
2256 const char *name;
2258 address_modes[] =
2260 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
2261 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
2262 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
2263 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
2264 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
2267 window = create_window();
2268 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2269 ok(!!d3d, "Failed to create a D3D object.\n");
2270 if (!(device = create_device(d3d, window, window, TRUE)))
2272 skip("Failed to create a D3D device, skipping tests.\n");
2273 goto done;
2276 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2277 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2278 if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP))
2280 skip("No cube texture support, skipping tests.\n");
2281 IDirect3DDevice9_Release(device);
2282 goto done;
2285 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
2286 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
2287 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2288 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
2290 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
2291 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
2292 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
2294 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
2295 D3DPOOL_DEFAULT, &texture, NULL);
2296 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
2298 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
2299 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2301 for (y = 0; y < 128; ++y)
2303 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2304 for (x = 0; x < 64; ++x)
2306 *ptr++ = 0xff0000ff;
2308 for (x = 64; x < 128; ++x)
2310 *ptr++ = 0xffff0000;
2314 hr = IDirect3DSurface9_UnlockRect(surface);
2315 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2317 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
2318 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
2320 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
2321 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
2323 IDirect3DSurface9_Release(face_surface);
2325 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
2326 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2328 for (y = 0; y < 128; ++y)
2330 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2331 for (x = 0; x < 64; ++x)
2333 *ptr++ = 0xffff0000;
2335 for (x = 64; x < 128; ++x)
2337 *ptr++ = 0xff0000ff;
2341 hr = IDirect3DSurface9_UnlockRect(surface);
2342 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2344 /* Create cube faces */
2345 for (face = 1; face < 6; ++face)
2347 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
2348 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
2350 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
2351 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
2353 IDirect3DSurface9_Release(face_surface);
2356 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
2357 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2359 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
2360 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2361 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
2362 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2363 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
2364 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
2366 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2367 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2369 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
2371 DWORD color;
2373 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
2374 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
2375 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
2376 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
2378 hr = IDirect3DDevice9_BeginScene(device);
2379 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2381 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2382 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2384 hr = IDirect3DDevice9_EndScene(device);
2385 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2387 color = getPixelColor(device, 320, 240);
2388 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
2389 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
2390 color, address_modes[x].name);
2392 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2393 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2395 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
2396 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
2399 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2400 IDirect3DCubeTexture9_Release(texture);
2401 IDirect3DSurface9_Release(surface);
2402 refcount = IDirect3DDevice9_Release(device);
2403 ok(!refcount, "Device has %u references left.\n", refcount);
2404 done:
2405 IDirect3D9_Release(d3d);
2406 DestroyWindow(window);
2409 static void offscreen_test(void)
2411 IDirect3DSurface9 *backbuffer, *offscreen;
2412 IDirect3DTexture9 *offscreenTexture;
2413 IDirect3DDevice9 *device;
2414 IDirect3D9 *d3d;
2415 D3DCOLOR color;
2416 ULONG refcount;
2417 HWND window;
2418 HRESULT hr;
2420 static const float quad[][5] =
2422 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
2423 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
2424 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
2425 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
2428 window = create_window();
2429 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2430 ok(!!d3d, "Failed to create a D3D object.\n");
2431 if (!(device = create_device(d3d, window, window, TRUE)))
2433 skip("Failed to create a D3D device, skipping tests.\n");
2434 goto done;
2437 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
2438 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
2440 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2441 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
2442 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
2443 if (!offscreenTexture)
2445 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5.\n");
2446 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2447 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
2448 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
2449 if (!offscreenTexture)
2451 skip("Cannot create an offscreen render target.\n");
2452 IDirect3DDevice9_Release(device);
2453 goto done;
2457 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2458 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2460 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
2461 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
2463 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2464 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
2466 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
2467 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
2468 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2469 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
2470 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2471 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2472 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2473 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2474 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2475 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2477 hr = IDirect3DDevice9_BeginScene(device);
2478 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2480 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
2481 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2482 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 1.0f, 0);
2483 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2485 /* Draw without textures - Should result in a white quad. */
2486 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2487 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2489 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
2490 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2491 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)offscreenTexture);
2492 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2494 /* This time with the texture. */
2495 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2496 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2498 hr = IDirect3DDevice9_EndScene(device);
2499 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2501 /* Center quad - should be white */
2502 color = getPixelColor(device, 320, 240);
2503 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2504 /* Some quad in the cleared part of the texture */
2505 color = getPixelColor(device, 170, 240);
2506 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
2507 /* Part of the originally cleared back buffer */
2508 color = getPixelColor(device, 10, 10);
2509 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2510 color = getPixelColor(device, 10, 470);
2511 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2513 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2515 IDirect3DSurface9_Release(backbuffer);
2516 IDirect3DTexture9_Release(offscreenTexture);
2517 IDirect3DSurface9_Release(offscreen);
2518 refcount = IDirect3DDevice9_Release(device);
2519 ok(!refcount, "Device has %u references left.\n", refcount);
2520 done:
2521 IDirect3D9_Release(d3d);
2522 DestroyWindow(window);
2525 /* This test tests fog in combination with shaders.
2526 * What's tested: linear fog (vertex and table) with pixel shader
2527 * linear table fog with non foggy vertex shader
2528 * vertex fog with foggy vertex shader, non-linear
2529 * fog with shader, non-linear fog with foggy shader,
2530 * linear table fog with foggy shader */
2531 static void fog_with_shader_test(void)
2533 IDirect3DVertexShader9 *vertex_shader[4] = {NULL, NULL, NULL, NULL};
2534 IDirect3DPixelShader9 *pixel_shader[3] = {NULL, NULL, NULL};
2535 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
2536 IDirect3DDevice9 *device;
2537 unsigned int i, j;
2538 IDirect3D9 *d3d;
2539 ULONG refcount;
2540 D3DCAPS9 caps;
2541 DWORD color;
2542 HWND window;
2543 HRESULT hr;
2544 union
2546 float f;
2547 DWORD i;
2548 } start, end;
2550 /* basic vertex shader without fog computation ("non foggy") */
2551 static const DWORD vertex_shader_code1[] =
2553 0xfffe0101, /* vs_1_1 */
2554 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2555 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
2556 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2557 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
2558 0x0000ffff
2560 /* basic vertex shader with reversed fog computation ("foggy") */
2561 static const DWORD vertex_shader_code2[] =
2563 0xfffe0101, /* vs_1_1 */
2564 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2565 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
2566 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
2567 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2568 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
2569 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
2570 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
2571 0x0000ffff
2573 /* basic vertex shader with reversed fog computation ("foggy"), vs_2_0 */
2574 static const DWORD vertex_shader_code3[] =
2576 0xfffe0200, /* vs_2_0 */
2577 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2578 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
2579 0x05000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
2580 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2581 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
2582 0x03000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
2583 0x03000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
2584 0x0000ffff
2586 /* basic pixel shader */
2587 static const DWORD pixel_shader_code[] =
2589 0xffff0101, /* ps_1_1 */
2590 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
2591 0x0000ffff
2593 static const DWORD pixel_shader_code2[] =
2595 0xffff0200, /* ps_2_0 */
2596 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
2597 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
2598 0x0000ffff
2600 struct
2602 struct vec3 position;
2603 DWORD diffuse;
2605 quad[] =
2607 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
2608 {{-1.0f, 1.0f, 0.0f}, 0xffff0000},
2609 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
2610 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000},
2612 static const D3DVERTEXELEMENT9 decl_elements[] =
2614 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2615 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
2616 D3DDECL_END()
2618 /* This reference data was collected on a nVidia GeForce 7600GS driver
2619 * version 84.19 DirectX version 9.0c on Windows XP. */
2620 static const struct test_data_t
2622 int vshader;
2623 int pshader;
2624 D3DFOGMODE vfog;
2625 D3DFOGMODE tfog;
2626 unsigned int color[11];
2628 test_data[] =
2630 /* only pixel shader: */
2631 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
2632 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2633 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2634 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
2635 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2636 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2637 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
2638 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2639 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2640 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2641 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2642 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2643 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
2644 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2645 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2647 /* vertex shader */
2648 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
2649 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2650 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2651 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
2652 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2653 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2654 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
2655 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2656 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2658 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
2659 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2660 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2661 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
2662 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2663 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2665 /* vertex shader and pixel shader */
2666 /* The next 4 tests would read the fog coord output, but it isn't available.
2667 * The result is a fully fogged quad, no matter what the Z coord is. This is on
2668 * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
2669 * These tests should be disabled if some other hardware behaves differently
2671 {1, 1, D3DFOG_NONE, D3DFOG_NONE,
2672 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2673 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2674 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2675 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2676 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2677 {1, 1, D3DFOG_EXP, D3DFOG_NONE,
2678 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2679 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2680 {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
2681 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2682 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2684 /* These use the Z coordinate with linear table fog */
2685 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
2686 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2687 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2688 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
2689 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2690 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2691 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
2692 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2693 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2694 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
2695 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2696 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2698 /* Non-linear table fog without fog coord */
2699 {1, 1, D3DFOG_NONE, D3DFOG_EXP,
2700 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
2701 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
2702 {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
2703 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
2704 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
2706 /* These tests fail on older Nvidia drivers */
2707 /* foggy vertex shader */
2708 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
2709 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2710 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2711 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
2712 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2713 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2714 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
2715 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2716 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2717 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
2718 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2719 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2721 {3, 0, D3DFOG_NONE, D3DFOG_NONE,
2722 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2723 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2724 {3, 0, D3DFOG_EXP, D3DFOG_NONE,
2725 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2726 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2727 {3, 0, D3DFOG_EXP2, D3DFOG_NONE,
2728 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2729 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2730 {3, 0, D3DFOG_LINEAR, D3DFOG_NONE,
2731 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2732 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2734 /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
2735 * all using the fixed fog-coord linear fog
2737 /* vs_1_1 with ps_1_1 */
2738 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
2739 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2740 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2741 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
2742 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2743 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2744 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
2745 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2746 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2747 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2748 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2749 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2751 /* vs_2_0 with ps_1_1 */
2752 {3, 1, D3DFOG_NONE, D3DFOG_NONE,
2753 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2754 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2755 {3, 1, D3DFOG_EXP, D3DFOG_NONE,
2756 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2757 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2758 {3, 1, D3DFOG_EXP2, D3DFOG_NONE,
2759 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2760 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2761 {3, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2762 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2763 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2765 /* vs_1_1 with ps_2_0 */
2766 {2, 2, D3DFOG_NONE, D3DFOG_NONE,
2767 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2768 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2769 {2, 2, D3DFOG_EXP, D3DFOG_NONE,
2770 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2771 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2772 {2, 2, D3DFOG_EXP2, D3DFOG_NONE,
2773 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2774 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2775 {2, 2, D3DFOG_LINEAR, D3DFOG_NONE,
2776 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2777 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2779 /* vs_2_0 with ps_2_0 */
2780 {3, 2, D3DFOG_NONE, D3DFOG_NONE,
2781 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2782 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2783 {3, 2, D3DFOG_EXP, D3DFOG_NONE,
2784 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2785 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2786 {3, 2, D3DFOG_EXP2, D3DFOG_NONE,
2787 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2788 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2789 {3, 2, D3DFOG_LINEAR, D3DFOG_NONE,
2790 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2791 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2793 /* These use table fog. Here the shader-provided fog coordinate is
2794 * ignored and the z coordinate used instead
2796 {2, 1, D3DFOG_NONE, D3DFOG_EXP,
2797 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
2798 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
2799 {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
2800 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
2801 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
2802 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
2803 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2804 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2806 static const D3DMATRIX identity =
2808 1.0f, 0.0f, 0.0f, 0.0f,
2809 0.0f, 1.0f, 0.0f, 0.0f,
2810 0.0f, 0.0f, 1.0f, 0.0f,
2811 0.0f, 0.0f, 0.0f, 1.0f,
2812 }}};
2814 window = create_window();
2815 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2816 ok(!!d3d, "Failed to create a D3D object.\n");
2817 if (!(device = create_device(d3d, window, window, TRUE)))
2819 skip("Failed to create a D3D device, skipping tests.\n");
2820 goto done;
2823 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2824 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2825 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0) || caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
2827 skip("No shader model 2 support, skipping tests.\n");
2828 IDirect3DDevice9_Release(device);
2829 goto done;
2832 /* NOTE: Changing these values will not affect the tests with foggy vertex
2833 * shader, as the values are hardcoded in the shader. */
2834 start.f = 0.1f;
2835 end.f = 0.9f;
2837 /* Some of the tests seem to depend on the projection matrix explicitly
2838 * being set to an identity matrix, even though that's the default.
2839 * (AMD Radeon HD 6310, Windows 7) */
2840 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
2841 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
2843 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
2844 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2845 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
2846 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2847 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code3, &vertex_shader[3]);
2848 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2849 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
2850 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2851 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code2, &pixel_shader[2]);
2852 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2853 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
2854 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
2856 /* Setup initial states: No lighting, fog on, fog color */
2857 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2858 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
2859 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
2860 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
2861 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xff00ff00 /* A nice green */);
2862 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
2863 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2864 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2866 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
2867 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
2868 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
2869 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
2871 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
2872 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
2873 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
2874 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
2875 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
2877 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
2879 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
2880 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2881 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
2882 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2883 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
2884 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2885 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
2886 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2888 for(j=0; j < 11; j++)
2890 /* Don't use the whole zrange to prevent rounding errors */
2891 quad[0].position.z = 0.001f + (float)j / 10.02f;
2892 quad[1].position.z = 0.001f + (float)j / 10.02f;
2893 quad[2].position.z = 0.001f + (float)j / 10.02f;
2894 quad[3].position.z = 0.001f + (float)j / 10.02f;
2896 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff00ff, 1.0f, 0);
2897 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2899 hr = IDirect3DDevice9_BeginScene(device);
2900 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
2902 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2903 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2905 hr = IDirect3DDevice9_EndScene(device);
2906 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
2908 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
2909 color = getPixelColor(device, 128, 240);
2910 ok(color_match(color, test_data[i].color[j], 13),
2911 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
2912 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
2915 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2917 IDirect3DVertexShader9_Release(vertex_shader[1]);
2918 IDirect3DVertexShader9_Release(vertex_shader[2]);
2919 IDirect3DVertexShader9_Release(vertex_shader[3]);
2920 IDirect3DPixelShader9_Release(pixel_shader[1]);
2921 IDirect3DPixelShader9_Release(pixel_shader[2]);
2922 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2923 refcount = IDirect3DDevice9_Release(device);
2924 ok(!refcount, "Device has %u references left.\n", refcount);
2925 done:
2926 IDirect3D9_Release(d3d);
2927 DestroyWindow(window);
2930 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
2931 unsigned int i, x, y;
2932 HRESULT hr;
2933 IDirect3DTexture9 *texture[2] = {NULL, NULL};
2934 D3DLOCKED_RECT locked_rect;
2936 /* Generate the textures */
2937 for(i=0; i<2; i++)
2939 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
2940 D3DPOOL_MANAGED, &texture[i], NULL);
2941 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
2943 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
2944 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2945 for (y = 0; y < 128; ++y)
2947 if(i)
2948 { /* Set up black texture with 2x2 texel white spot in the middle */
2949 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2950 for (x = 0; x < 128; ++x)
2952 *ptr++ = D3DCOLOR_ARGB(0xff, x * 2, y * 2, 0);
2955 else
2956 { /* Set up a displacement map which points away from the center parallel to the closest axis.
2957 * (if multiplied with bumpenvmat)
2959 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2960 for (x = 0; x < 128; ++x)
2962 if(abs(x-64)>abs(y-64))
2964 if(x < 64)
2965 *ptr++ = 0xc000;
2966 else
2967 *ptr++ = 0x4000;
2969 else
2971 if(y < 64)
2972 *ptr++ = 0x0040;
2973 else
2974 *ptr++ = 0x00c0;
2979 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
2980 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2982 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
2983 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2985 /* Disable texture filtering */
2986 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2987 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2988 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2989 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2991 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2992 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
2993 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2994 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
2998 /* Test the behavior of the texbem instruction with normal 2D and projective
2999 * 2D textures. */
3000 static void texbem_test(void)
3002 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
3003 /* Use asymmetric matrix to test loading. */
3004 float bumpenvmat[4] = {0.0f, 0.5f, -0.5f, 0.0f};
3005 IDirect3DPixelShader9 *pixel_shader = NULL;
3006 IDirect3DTexture9 *texture1, *texture2;
3007 IDirect3DTexture9 *texture = NULL;
3008 D3DLOCKED_RECT locked_rect;
3009 IDirect3DDevice9 *device;
3010 IDirect3D9 *d3d;
3011 ULONG refcount;
3012 D3DCAPS9 caps;
3013 DWORD color;
3014 HWND window;
3015 HRESULT hr;
3016 int i;
3018 static const DWORD pixel_shader_code[] =
3020 0xffff0101, /* ps_1_1*/
3021 0x00000042, 0xb00f0000, /* tex t0*/
3022 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
3023 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
3024 0x0000ffff
3026 static const DWORD double_texbem_code[] =
3028 0xffff0103, /* ps_1_3 */
3029 0x00000042, 0xb00f0000, /* tex t0 */
3030 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
3031 0x00000042, 0xb00f0002, /* tex t2 */
3032 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
3033 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
3034 0x0000ffff /* end */
3036 static const float quad[][7] =
3038 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
3039 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
3040 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
3041 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
3043 static const float quad_proj[][9] =
3045 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
3046 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
3047 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
3048 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
3050 static const float double_quad[] =
3052 -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3053 -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3054 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3055 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3057 static const D3DVERTEXELEMENT9 decl_elements[][4] =
3060 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3061 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3062 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
3063 D3DDECL_END()
3066 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3067 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3068 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
3069 D3DDECL_END()
3073 window = create_window();
3074 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3075 ok(!!d3d, "Failed to create a D3D object.\n");
3076 if (!(device = create_device(d3d, window, window, TRUE)))
3078 skip("Failed to create a D3D device, skipping tests.\n");
3079 goto done;
3082 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3083 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3084 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
3086 skip("No ps_1_1 support, skipping tests.\n");
3087 IDirect3DDevice9_Release(device);
3088 goto done;
3091 generate_bumpmap_textures(device);
3093 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
3094 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
3095 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
3096 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
3097 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
3099 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
3100 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
3102 for(i=0; i<2; i++)
3104 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
3105 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
3107 if(i)
3109 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
3110 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
3113 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
3114 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
3115 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
3116 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
3118 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
3119 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
3120 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
3121 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3123 hr = IDirect3DDevice9_BeginScene(device);
3124 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
3126 if(!i)
3127 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
3128 else
3129 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
3130 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
3132 hr = IDirect3DDevice9_EndScene(device);
3133 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
3135 /* The Window 8 testbot (WARP) seems to use the transposed
3136 * D3DTSS_BUMPENVMAT matrix. */
3137 color = getPixelColor(device, 160, 240);
3138 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00007e00, 4)),
3139 "Got unexpected color 0x%08x.\n", color);
3140 color = getPixelColor(device, 480, 240);
3141 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00fe7e00, 4)),
3142 "Got unexpected color 0x%08x.\n", color);
3143 color = getPixelColor(device, 320, 120);
3144 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x0080fe00, 4)),
3145 "Got unexpected color 0x%08x.\n", color);
3146 color = getPixelColor(device, 320, 360);
3147 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00800000, 4)),
3148 "Got unexpected color 0x%08x.\n", color);
3150 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3151 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3153 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3154 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3155 IDirect3DPixelShader9_Release(pixel_shader);
3157 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3158 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
3159 IDirect3DVertexDeclaration9_Release(vertex_declaration);
3162 /* clean up */
3163 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
3164 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
3166 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3167 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
3169 for(i=0; i<2; i++)
3171 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
3172 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
3173 IDirect3DTexture9_Release(texture); /* For the GetTexture */
3174 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
3175 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
3176 IDirect3DTexture9_Release(texture);
3179 /* Test double texbem */
3180 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
3181 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
3182 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
3183 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
3184 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
3185 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
3186 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
3187 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
3189 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
3190 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3191 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
3192 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
3194 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3195 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3197 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
3198 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3199 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
3200 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
3201 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
3202 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3205 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
3206 #define tex 0x00ff0000
3207 #define tex1 0x0000ff00
3208 #define origin 0x000000ff
3209 static const DWORD pixel_data[] = {
3210 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3211 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3212 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3213 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3214 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
3215 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3216 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3217 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3219 #undef tex1
3220 #undef tex2
3221 #undef origin
3223 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
3224 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3225 for(i = 0; i < 8; i++) {
3226 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
3228 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
3229 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3232 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3233 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3234 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
3235 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3236 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
3237 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3238 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
3239 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3240 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
3241 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
3242 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
3243 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
3245 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
3246 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
3247 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
3248 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3249 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
3250 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3251 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
3252 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3253 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
3254 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3256 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
3257 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
3258 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
3259 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3260 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
3261 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3262 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
3263 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3264 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
3265 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3267 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3268 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3269 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3270 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3271 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3272 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3273 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3274 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3275 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3276 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3277 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3278 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3279 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3280 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3281 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3282 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3284 hr = IDirect3DDevice9_BeginScene(device);
3285 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3286 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
3287 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
3288 hr = IDirect3DDevice9_EndScene(device);
3289 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3290 /* The Window 8 testbot (WARP) seems to use the transposed
3291 * D3DTSS_BUMPENVMAT matrix. */
3292 color = getPixelColor(device, 320, 240);
3293 ok(color_match(color, 0x00ffff00, 1) || broken(color_match(color, 0x0000ffff, 1)),
3294 "Got unexpected color 0x%08x.\n", color);
3296 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3297 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3299 IDirect3DPixelShader9_Release(pixel_shader);
3300 IDirect3DTexture9_Release(texture);
3301 IDirect3DTexture9_Release(texture1);
3302 IDirect3DTexture9_Release(texture2);
3303 refcount = IDirect3DDevice9_Release(device);
3304 ok(!refcount, "Device has %u references left.\n", refcount);
3305 done:
3306 IDirect3D9_Release(d3d);
3307 DestroyWindow(window);
3310 static void z_range_test(void)
3312 IDirect3DVertexShader9 *shader;
3313 IDirect3DDevice9 *device;
3314 IDirect3D9 *d3d;
3315 ULONG refcount;
3316 D3DCAPS9 caps;
3317 DWORD color;
3318 HWND window;
3319 HRESULT hr;
3321 static const struct
3323 struct vec3 position;
3324 DWORD diffuse;
3326 quad[] =
3328 {{-1.0f, 0.0f, 1.1f}, 0xffff0000},
3329 {{-1.0f, 1.0f, 1.1f}, 0xffff0000},
3330 {{ 1.0f, 0.0f, -1.1f}, 0xffff0000},
3331 {{ 1.0f, 1.0f, -1.1f}, 0xffff0000},
3333 quad2[] =
3335 {{-1.0f, 0.0f, 1.1f}, 0xff0000ff},
3336 {{-1.0f, 1.0f, 1.1f}, 0xff0000ff},
3337 {{ 1.0f, 0.0f, -1.1f}, 0xff0000ff},
3338 {{ 1.0f, 1.0f, -1.1f}, 0xff0000ff},
3340 static const struct
3342 struct vec4 position;
3343 DWORD diffuse;
3345 quad3[] =
3347 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xffffff00},
3348 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xffffff00},
3349 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xffffff00},
3350 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xffffff00},
3352 quad4[] =
3354 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xff00ff00},
3355 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xff00ff00},
3356 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xff00ff00},
3357 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xff00ff00},
3359 static const DWORD shader_code[] =
3361 0xfffe0101, /* vs_1_1 */
3362 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
3363 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
3364 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
3365 0x0000ffff /* end */
3367 static const float color_const_1[] = {1.0f, 0.0f, 0.0f, 1.0f};
3368 static const float color_const_2[] = {0.0f, 0.0f, 1.0f, 1.0f};
3370 window = create_window();
3371 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3372 ok(!!d3d, "Failed to create a D3D object.\n");
3373 if (!(device = create_device(d3d, window, window, TRUE)))
3375 skip("Failed to create a D3D device, skipping tests.\n");
3376 goto done;
3379 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3380 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3382 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
3383 * then call Present. Then clear the color buffer to make sure it has some defined content
3384 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
3385 * by the depth value. */
3386 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75f, 0);
3387 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3388 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3389 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
3390 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
3391 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3393 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3394 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
3395 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
3396 ok(SUCCEEDED(hr), "Failed to enable clipping, hr %#x.\n", hr);
3397 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3398 ok(SUCCEEDED(hr), "Failed to enable z test, hr %#x.\n", hr);
3399 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3400 ok(SUCCEEDED(hr), "Failed to disable z writes, hr %#x.\n", hr);
3401 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3402 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3403 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3404 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
3406 hr = IDirect3DDevice9_BeginScene(device);
3407 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3409 /* Test the untransformed vertex path */
3410 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
3411 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3412 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
3413 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3414 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
3415 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3417 /* Test the transformed vertex path */
3418 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
3419 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
3421 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
3422 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3423 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3424 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3425 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
3426 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3428 hr = IDirect3DDevice9_EndScene(device);
3429 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3431 /* Do not test the exact corner pixels, but go pretty close to them */
3433 /* Clipped because z > 1.0 */
3434 color = getPixelColor(device, 28, 238);
3435 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3436 color = getPixelColor(device, 28, 241);
3437 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
3438 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3439 else
3440 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
3442 /* Not clipped, > z buffer clear value(0.75).
3444 * On the r500 driver on Windows D3DCMP_GREATER and D3DCMP_GREATEREQUAL are broken for depth
3445 * values > 0.5. The range appears to be distorted, apparently an incoming value of ~0.875 is
3446 * equal to a stored depth buffer value of 0.5. */
3447 color = getPixelColor(device, 31, 238);
3448 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3449 color = getPixelColor(device, 31, 241);
3450 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
3451 color = getPixelColor(device, 100, 238);
3452 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
3453 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3454 color = getPixelColor(device, 100, 241);
3455 ok(color_match(color, 0x00ffff00, 0) || broken(color_match(color, 0x00ffffff, 0)),
3456 "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
3458 /* Not clipped, < z buffer clear value */
3459 color = getPixelColor(device, 104, 238);
3460 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3461 color = getPixelColor(device, 104, 241);
3462 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
3463 color = getPixelColor(device, 318, 238);
3464 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3465 color = getPixelColor(device, 318, 241);
3466 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
3468 /* Clipped because z < 0.0 */
3469 color = getPixelColor(device, 321, 238);
3470 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3471 color = getPixelColor(device, 321, 241);
3472 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
3473 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3474 else
3475 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3477 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3478 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
3480 /* Test the shader path */
3481 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
3483 skip("Vertex shaders not supported, skipping tests.\n");
3484 IDirect3DDevice9_Release(device);
3485 goto done;
3487 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
3488 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
3490 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
3491 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3493 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3494 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
3495 hr = IDirect3DDevice9_SetVertexShader(device, shader);
3496 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
3498 hr = IDirect3DDevice9_BeginScene(device);
3499 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3501 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, color_const_1, 1);
3502 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
3503 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
3504 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3506 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
3507 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3508 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, color_const_2, 1);
3509 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
3510 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
3511 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3513 hr = IDirect3DDevice9_EndScene(device);
3514 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3516 IDirect3DVertexShader9_Release(shader);
3518 /* Z < 1.0 */
3519 color = getPixelColor(device, 28, 238);
3520 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3522 /* 1.0 < z < 0.75 */
3523 color = getPixelColor(device, 31, 238);
3524 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3525 color = getPixelColor(device, 100, 238);
3526 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
3527 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3529 /* 0.75 < z < 0.0 */
3530 color = getPixelColor(device, 104, 238);
3531 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3532 color = getPixelColor(device, 318, 238);
3533 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3535 /* 0.0 < z */
3536 color = getPixelColor(device, 321, 238);
3537 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3539 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3540 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
3542 refcount = IDirect3DDevice9_Release(device);
3543 ok(!refcount, "Device has %u references left.\n", refcount);
3544 done:
3545 IDirect3D9_Release(d3d);
3546 DestroyWindow(window);
3549 static void fill_surface(IDirect3DSurface9 *surface, DWORD color, DWORD flags)
3551 D3DSURFACE_DESC desc;
3552 D3DLOCKED_RECT l;
3553 HRESULT hr;
3554 unsigned int x, y;
3555 DWORD *mem;
3557 memset(&desc, 0, sizeof(desc));
3558 memset(&l, 0, sizeof(l));
3559 hr = IDirect3DSurface9_GetDesc(surface, &desc);
3560 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
3561 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, flags);
3562 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
3563 if(FAILED(hr)) return;
3565 for(y = 0; y < desc.Height; y++)
3567 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
3568 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
3570 mem[x] = color;
3573 hr = IDirect3DSurface9_UnlockRect(surface);
3574 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
3577 static void stretchrect_test(void)
3579 IDirect3DSurface9 *surf_tex_rt32, *surf_tex_rt64, *surf_tex_rt_dest64, *surf_tex_rt_dest640_480;
3580 IDirect3DSurface9 *surf_offscreen32, *surf_offscreen64, *surf_offscreen_dest64;
3581 IDirect3DTexture9 *tex_rt32, *tex_rt64, *tex_rt_dest64, *tex_rt_dest640_480;
3582 IDirect3DSurface9 *surf_tex32, *surf_tex64, *surf_tex_dest64;
3583 IDirect3DSurface9 *surf_rt32, *surf_rt64, *surf_rt_dest64;
3584 IDirect3DTexture9 *tex32, *tex64, *tex_dest64;
3585 IDirect3DSurface9 *surf_temp32, *surf_temp64;
3586 IDirect3DSurface9 *backbuffer;
3587 IDirect3DDevice9 *device;
3588 IDirect3D9 *d3d;
3589 D3DCOLOR color;
3590 ULONG refcount;
3591 HWND window;
3592 HRESULT hr;
3594 static const RECT src_rect = {0, 0, 640, 480};
3595 static const RECT src_rect_flipy = {0, 480, 640, 0};
3596 static const RECT dst_rect = {0, 0, 640, 480};
3597 static const RECT dst_rect_flipy = {0, 480, 640, 0};
3598 static const RECT src_rect64 = {0, 0, 64, 64};
3599 static const RECT src_rect64_flipy = {0, 64, 64, 0};
3600 static const RECT dst_rect64 = {0, 0, 64, 64};
3601 static const RECT dst_rect64_flipy = {0, 64, 64, 0};
3603 window = create_window();
3604 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3605 ok(!!d3d, "Failed to create a D3D object.\n");
3606 if (!(device = create_device(d3d, window, window, TRUE)))
3608 skip("Failed to create a D3D device, skipping tests.\n");
3609 goto done;
3612 /* Create our temporary surfaces in system memory. */
3613 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
3614 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
3615 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3616 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
3617 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
3618 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3620 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT. */
3621 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
3622 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
3623 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3624 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
3625 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
3626 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3627 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
3628 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
3629 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3631 /* Create render target surfaces. */
3632 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32,
3633 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
3634 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
3635 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64,
3636 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
3637 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
3638 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64,
3639 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
3640 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
3641 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
3642 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
3644 /* Create render target textures. */
3645 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET,
3646 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
3647 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3648 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET,
3649 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
3650 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3651 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET,
3652 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
3653 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3654 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET,
3655 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
3656 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3657 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
3658 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3659 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
3660 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3661 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
3662 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3663 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
3664 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3666 /* Create regular textures in D3DPOOL_DEFAULT. */
3667 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
3668 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3669 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
3670 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3671 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
3672 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3673 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
3674 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3675 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
3676 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3677 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
3678 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3680 /**********************************************************************
3681 * Tests for when the source parameter is an offscreen plain surface. *
3682 **********************************************************************/
3684 /* Fill the offscreen 64x64 surface with green. */
3685 fill_surface(surf_offscreen64, 0xff00ff00, 0);
3687 /* offscreenplain ==> offscreenplain, same size. */
3688 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, D3DTEXF_NONE);
3689 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3690 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
3691 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
3692 /* Blit without scaling. */
3693 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3694 surf_offscreen_dest64, &dst_rect64, D3DTEXF_NONE);
3695 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3696 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3697 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy,
3698 surf_offscreen_dest64, &dst_rect64, D3DTEXF_NONE);
3699 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3700 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3701 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3702 surf_offscreen_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3703 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3705 /* offscreenplain ==> rendertarget texture, same size. */
3706 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3707 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3708 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3709 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3710 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3711 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3712 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
3713 /* Blit without scaling. */
3714 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3715 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3716 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3717 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3718 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy,
3719 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3720 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3721 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3722 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3723 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3724 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3726 /* offscreenplain ==> rendertarget surface, same size. */
3727 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3728 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3729 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3730 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
3731 /* Blit without scaling. */
3732 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3733 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3734 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3735 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3736 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy,
3737 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3738 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3739 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3740 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3741 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3742 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3744 /* offscreenplain ==> texture, same size (should fail). */
3745 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3746 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3748 /* Fill the smaller offscreen surface with red. */
3749 fill_surface(surf_offscreen32, 0xffff0000, 0);
3751 /* offscreenplain ==> offscreenplain, scaling (should fail). */
3752 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3753 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3755 /* offscreenplain ==> rendertarget texture, scaling. */
3756 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3757 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3758 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3759 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3760 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3761 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3762 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3764 /* offscreenplain ==> rendertarget surface, scaling. */
3765 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3766 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3767 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3768 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3770 /* offscreenplain ==> texture, scaling (should fail). */
3771 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3772 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3774 /*************************************************************
3775 * Tests for when the source parameter is a regular texture. *
3776 *************************************************************/
3778 /* Fill the surface of the regular texture with blue. */
3779 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT. */
3780 fill_surface(surf_temp64, 0xff0000ff, 0);
3781 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
3782 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3784 /* texture ==> offscreenplain, same size. */
3785 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3786 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3788 /* texture ==> rendertarget texture, same size. */
3789 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3790 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3791 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3792 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3793 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3794 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3795 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
3796 /* Blit without scaling. */
3797 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3798 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3799 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3800 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3801 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy,
3802 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3803 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3804 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3805 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3806 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3807 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3809 /* texture ==> rendertarget surface, same size. */
3810 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3811 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3812 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3813 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
3814 /* Blit without scaling. */
3815 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3816 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3817 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3818 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3819 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy,
3820 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3821 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3822 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3823 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3824 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3825 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3827 /* texture ==> texture, same size (should fail). */
3828 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3829 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3831 /* Fill the surface of the smaller regular texture with red. */
3832 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT. */
3833 fill_surface(surf_temp32, 0xffff0000, 0);
3834 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
3835 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3837 /* texture ==> offscreenplain, scaling (should fail). */
3838 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3839 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3841 /* texture ==> rendertarget texture, scaling. */
3842 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3843 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3844 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3845 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3846 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3847 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3848 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3850 /* texture ==> rendertarget surface, scaling. */
3851 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3852 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3853 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3854 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3856 /* texture ==> texture, scaling (should fail). */
3857 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3858 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3860 /******************************************************************
3861 * Tests for when the source parameter is a rendertarget texture. *
3862 ******************************************************************/
3864 /* Fill the surface of the rendertarget texture with white. */
3865 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT. */
3866 fill_surface(surf_temp64, 0xffffffff, 0);
3867 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
3868 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3870 /* rendertarget texture ==> offscreenplain, same size. */
3871 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3872 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3874 /* rendertarget texture ==> rendertarget texture, same size. */
3875 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3876 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3877 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3878 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3879 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3880 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3881 ok(color == 0xffffffff, "Got unexpected color 0x%08x.\n", color);
3882 /* Blit without scaling. */
3883 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3884 surf_tex_rt_dest64, &dst_rect64, 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, surf_tex_rt64, &src_rect64_flipy,
3888 surf_tex_rt_dest64, &dst_rect64, 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, surf_tex_rt64, &src_rect64,
3892 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3893 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3895 /* rendertarget texture ==> rendertarget surface, same size. */
3896 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3897 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3898 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3899 ok(color == 0xffffffff, "Got unexpected color 0x%08x.\n", color);
3900 /* Blit without scaling. */
3901 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3902 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3903 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3904 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3905 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy,
3906 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3907 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3908 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3909 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3910 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3911 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3913 /* rendertarget texture ==> texture, same size (should fail). */
3914 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3915 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3917 /* Fill the surface of the smaller rendertarget texture with red. */
3918 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT. */
3919 fill_surface(surf_temp32, 0xffff0000, 0);
3920 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
3921 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3923 /* rendertarget texture ==> offscreenplain, scaling (should fail). */
3924 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3925 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3927 /* rendertarget texture ==> rendertarget texture, scaling. */
3928 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3929 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3930 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3931 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3932 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3933 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3934 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3936 /* rendertarget texture ==> rendertarget surface, scaling. */
3937 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3938 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3939 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3940 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3942 /* rendertarget texture ==> texture, scaling (should fail). */
3943 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3944 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3946 /******************************************************************
3947 * Tests for when the source parameter is a rendertarget surface. *
3948 ******************************************************************/
3950 /* Fill the surface of the rendertarget surface with black. */
3951 fill_surface(surf_rt64, 0xff000000, 0);
3953 /* rendertarget texture ==> offscreenplain, same size. */
3954 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3955 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3957 /* rendertarget surface ==> rendertarget texture, same size. */
3958 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3959 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3960 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3961 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3962 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3963 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3964 ok(color == 0xff000000, "Got unexpected color 0x%08x.\n", color);
3965 /* Blit without scaling. */
3966 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3967 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3968 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3969 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3970 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy,
3971 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3972 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3973 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3974 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3975 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3976 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3978 /* rendertarget surface ==> rendertarget surface, same size. */
3979 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3980 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3981 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3982 ok(color == 0xff000000, "Got unexpected color 0x%08x.\n", color);
3983 /* Blit without scaling. */
3984 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3985 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3986 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3987 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3988 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy,
3989 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3990 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3991 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3992 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3993 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3994 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3996 /* rendertarget surface ==> texture, same size (should fail). */
3997 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3998 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4000 /* Fill the surface of the smaller rendertarget texture with red. */
4001 fill_surface(surf_rt32, 0xffff0000, 0);
4003 /* rendertarget surface ==> offscreenplain, scaling (should fail). */
4004 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
4005 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4007 /* rendertarget surface ==> rendertarget texture, scaling. */
4008 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
4009 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4010 /* We can't lock rendertarget textures, so copy to our temp surface first. */
4011 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
4012 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
4013 color = getPixelColorFromSurface(surf_temp64, 48, 48);
4014 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
4016 /* rendertarget surface ==> rendertarget surface, scaling. */
4017 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
4018 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4019 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
4020 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
4022 /* rendertarget surface ==> texture, scaling (should fail). */
4023 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
4024 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4026 /* backbuffer ==> surface tests (no scaling). */
4027 /* Blit with NULL rectangles. */
4028 hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, D3DTEXF_NONE);
4029 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4030 /* Blit without scaling. */
4031 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect,
4032 surf_tex_rt_dest640_480, &dst_rect, D3DTEXF_NONE);
4033 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4034 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
4035 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy,
4036 surf_tex_rt_dest640_480, &dst_rect, D3DTEXF_NONE);
4037 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4038 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
4039 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect,
4040 surf_tex_rt_dest640_480, &dst_rect_flipy, D3DTEXF_NONE);
4041 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4043 /* TODO: Test format conversions. */
4045 IDirect3DSurface9_Release(backbuffer);
4046 IDirect3DSurface9_Release(surf_rt32);
4047 IDirect3DSurface9_Release(surf_rt64);
4048 IDirect3DSurface9_Release(surf_rt_dest64);
4049 IDirect3DSurface9_Release(surf_temp32);
4050 IDirect3DSurface9_Release(surf_temp64);
4051 IDirect3DSurface9_Release(surf_offscreen32);
4052 IDirect3DSurface9_Release(surf_offscreen64);
4053 IDirect3DSurface9_Release(surf_offscreen_dest64);
4054 IDirect3DSurface9_Release(surf_tex_rt32);
4055 IDirect3DTexture9_Release(tex_rt32);
4056 IDirect3DSurface9_Release(surf_tex_rt64);
4057 IDirect3DTexture9_Release(tex_rt64);
4058 IDirect3DSurface9_Release(surf_tex_rt_dest64);
4059 IDirect3DTexture9_Release(tex_rt_dest64);
4060 IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
4061 IDirect3DTexture9_Release(tex_rt_dest640_480);
4062 IDirect3DSurface9_Release(surf_tex32);
4063 IDirect3DTexture9_Release(tex32);
4064 IDirect3DSurface9_Release(surf_tex64);
4065 IDirect3DTexture9_Release(tex64);
4066 IDirect3DSurface9_Release(surf_tex_dest64);
4067 IDirect3DTexture9_Release(tex_dest64);
4068 refcount = IDirect3DDevice9_Release(device);
4069 ok(!refcount, "Device has %u references left.\n", refcount);
4070 done:
4071 IDirect3D9_Release(d3d);
4072 DestroyWindow(window);
4075 static void maxmip_test(void)
4077 IDirect3DTexture9 *texture;
4078 IDirect3DSurface9 *surface;
4079 IDirect3DDevice9 *device;
4080 IDirect3D9 *d3d;
4081 D3DCOLOR color;
4082 ULONG refcount;
4083 D3DCAPS9 caps;
4084 HWND window;
4085 HRESULT hr;
4086 DWORD ret;
4088 static const struct
4090 struct
4092 float x, y, z;
4093 float s, t;
4095 v[4];
4097 quads[] =
4100 {-1.0, -1.0, 0.0, 0.0, 0.0},
4101 {-1.0, 0.0, 0.0, 0.0, 1.0},
4102 { 0.0, -1.0, 0.0, 1.0, 0.0},
4103 { 0.0, 0.0, 0.0, 1.0, 1.0},
4106 { 0.0, -1.0, 0.0, 0.0, 0.0},
4107 { 0.0, 0.0, 0.0, 0.0, 1.0},
4108 { 1.0, -1.0, 0.0, 1.0, 0.0},
4109 { 1.0, 0.0, 0.0, 1.0, 1.0},
4112 { 0.0, 0.0, 0.0, 0.0, 0.0},
4113 { 0.0, 1.0, 0.0, 0.0, 1.0},
4114 { 1.0, 0.0, 0.0, 1.0, 0.0},
4115 { 1.0, 1.0, 0.0, 1.0, 1.0},
4118 {-1.0, 0.0, 0.0, 0.0, 0.0},
4119 {-1.0, 1.0, 0.0, 0.0, 1.0},
4120 { 0.0, 0.0, 0.0, 1.0, 0.0},
4121 { 0.0, 1.0, 0.0, 1.0, 1.0},
4125 window = create_window();
4126 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4127 ok(!!d3d, "Failed to create a D3D object.\n");
4128 if (!(device = create_device(d3d, window, window, TRUE)))
4130 skip("Failed to create a D3D device, skipping tests.\n");
4131 goto done;
4134 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4135 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4136 if (!(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP))
4138 skip("No mipmap support, skipping tests.\n");
4139 IDirect3DDevice9_Release(device);
4140 goto done;
4143 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0,
4144 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
4145 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
4147 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4148 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
4149 fill_surface(surface, 0xffff0000, 0);
4150 IDirect3DSurface9_Release(surface);
4151 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
4152 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
4153 fill_surface(surface, 0xff00ff00, 0);
4154 IDirect3DSurface9_Release(surface);
4155 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
4156 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
4157 fill_surface(surface, 0xff0000ff, 0);
4158 IDirect3DSurface9_Release(surface);
4160 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4161 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4162 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4163 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4165 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4166 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4167 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4168 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4170 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
4171 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4173 hr = IDirect3DDevice9_BeginScene(device);
4174 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4176 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
4177 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4178 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
4179 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4181 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
4182 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4183 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
4184 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4186 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4187 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4188 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
4189 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4191 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
4192 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4193 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
4194 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4196 hr = IDirect3DDevice9_EndScene(device);
4197 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4199 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
4200 color = getPixelColor(device, 160, 360);
4201 ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
4202 color = getPixelColor(device, 480, 360);
4203 ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
4204 color = getPixelColor(device, 480, 120);
4205 ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
4206 color = getPixelColor(device, 160, 120);
4207 ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
4208 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4209 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4211 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4212 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4214 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
4215 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4217 hr = IDirect3DDevice9_BeginScene(device);
4218 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4220 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
4221 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4222 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
4223 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4225 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
4226 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4227 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
4228 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4230 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4231 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4232 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
4233 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4235 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
4236 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4237 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
4238 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4240 hr = IDirect3DDevice9_EndScene(device);
4241 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4243 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
4244 * level 3 (> levels in texture) samples from the highest level in the
4245 * texture (level 2). */
4246 color = getPixelColor(device, 160, 360);
4247 ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
4248 color = getPixelColor(device, 480, 360);
4249 ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
4250 color = getPixelColor(device, 480, 120);
4251 ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
4252 color = getPixelColor(device, 160, 120);
4253 ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
4254 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4255 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4257 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
4258 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4260 hr = IDirect3DDevice9_BeginScene(device);
4261 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4263 /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
4264 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4265 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4266 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
4267 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4268 ret = IDirect3DTexture9_SetLOD(texture, 1);
4269 ok(ret == 0, "Got unexpected LOD %u.\n", ret);
4270 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
4271 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4273 /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
4274 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4275 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4276 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
4277 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4278 ret = IDirect3DTexture9_SetLOD(texture, 2);
4279 ok(ret == 1, "Got unexpected LOD %u.\n", ret);
4280 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
4281 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4283 /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
4284 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4285 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4286 ret = IDirect3DTexture9_SetLOD(texture, 1);
4287 ok(ret == 2, "Got unexpected LOD %u.\n", ret);
4288 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
4289 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4291 /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
4292 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4293 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4294 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4295 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4296 ret = IDirect3DTexture9_SetLOD(texture, 1);
4297 ok(ret == 1, "Got unexpected LOD %u.\n", ret);
4298 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
4299 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4301 hr = IDirect3DDevice9_EndScene(device);
4302 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4304 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
4305 * level 3 (> levels in texture) samples from the highest level in the
4306 * texture (level 2). */
4307 color = getPixelColor(device, 160, 360);
4308 ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
4309 color = getPixelColor(device, 480, 360);
4310 ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
4311 color = getPixelColor(device, 480, 120);
4312 ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
4313 color = getPixelColor(device, 160, 120);
4314 ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
4316 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4317 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4319 IDirect3DTexture9_Release(texture);
4320 refcount = IDirect3DDevice9_Release(device);
4321 ok(!refcount, "Device has %u references left.\n", refcount);
4322 done:
4323 IDirect3D9_Release(d3d);
4324 DestroyWindow(window);
4327 static void release_buffer_test(void)
4329 IDirect3DVertexBuffer9 *vb;
4330 IDirect3DIndexBuffer9 *ib;
4331 IDirect3DDevice9 *device;
4332 IDirect3D9 *d3d;
4333 D3DCOLOR color;
4334 ULONG refcount;
4335 HWND window;
4336 HRESULT hr;
4337 BYTE *data;
4338 LONG ref;
4340 static const short indices[] = {3, 4, 5};
4341 static const struct
4343 struct vec3 position;
4344 DWORD diffuse;
4346 quad[] =
4348 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
4349 {{-1.0f, 1.0f, 0.1f}, 0xffff0000},
4350 {{ 1.0f, 1.0f, 0.1f}, 0xffff0000},
4352 {{-1.0f, -1.0f, 0.1f}, 0xff00ff00},
4353 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
4354 {{ 1.0f, 1.0f, 0.1f}, 0xff00ff00},
4357 window = create_window();
4358 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4359 ok(!!d3d, "Failed to create a D3D object.\n");
4360 if (!(device = create_device(d3d, window, window, TRUE)))
4362 skip("Failed to create a D3D device, skipping tests.\n");
4363 goto done;
4366 /* Index and vertex buffers should always be creatable */
4367 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0,
4368 D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &vb, NULL);
4369 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
4370 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
4371 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
4372 memcpy(data, quad, sizeof(quad));
4373 hr = IDirect3DVertexBuffer9_Unlock(vb);
4374 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
4376 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0,
4377 D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
4378 ok(SUCCEEDED(hr), "Failed to create index buffer, hr %#x.\n", hr);
4379 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
4380 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
4381 memcpy(data, indices, sizeof(indices));
4382 hr = IDirect3DIndexBuffer9_Unlock(ib);
4383 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
4385 hr = IDirect3DDevice9_SetIndices(device, ib);
4386 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
4387 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
4388 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
4389 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
4390 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4391 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4392 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4394 /* Now destroy the bound index buffer and draw again */
4395 ref = IDirect3DIndexBuffer9_Release(ib);
4396 ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
4398 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4399 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
4401 hr = IDirect3DDevice9_BeginScene(device);
4402 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4403 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent
4404 * D3D from making assumptions about the indices or vertices. */
4405 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
4406 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4407 hr = IDirect3DDevice9_EndScene(device);
4408 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4410 color = getPixelColor(device, 160, 120);
4411 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1), "Got unexpected color 0x%08x.\n", color);
4412 color = getPixelColor(device, 480, 360);
4413 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1), "Got unexpected color 0x%08x.\n", color);
4415 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4416 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4418 /* Index buffer was already destroyed as part of the test */
4419 IDirect3DVertexBuffer9_Release(vb);
4420 refcount = IDirect3DDevice9_Release(device);
4421 ok(!refcount, "Device has %u references left.\n", refcount);
4422 done:
4423 IDirect3D9_Release(d3d);
4424 DestroyWindow(window);
4427 static void float_texture_test(void)
4429 IDirect3DTexture9 *texture;
4430 IDirect3DDevice9 *device;
4431 D3DLOCKED_RECT lr;
4432 IDirect3D9 *d3d;
4433 ULONG refcount;
4434 float *data;
4435 DWORD color;
4436 HWND window;
4437 HRESULT hr;
4439 static const float quad[] =
4441 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
4442 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
4443 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
4444 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4447 window = create_window();
4448 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4449 ok(!!d3d, "Failed to create a D3D object.\n");
4450 if (!(device = create_device(d3d, window, window, TRUE)))
4452 skip("Failed to create a D3D device, skipping tests.\n");
4453 goto done;
4456 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
4457 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK)
4459 skip("D3DFMT_R32F textures not supported\n");
4460 IDirect3DDevice9_Release(device);
4461 goto done;
4464 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F, D3DPOOL_MANAGED, &texture, NULL);
4465 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
4467 memset(&lr, 0, sizeof(lr));
4468 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4469 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
4470 data = lr.pBits;
4471 *data = 0.0;
4472 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4473 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
4475 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4476 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4477 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
4478 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4480 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4481 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
4483 hr = IDirect3DDevice9_BeginScene(device);
4484 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4485 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4486 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4487 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4488 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4489 hr = IDirect3DDevice9_EndScene(device);
4490 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4492 color = getPixelColor(device, 240, 320);
4493 ok(color == 0x0000ffff, "R32F with value 0.0 has color %08x, expected 0x0000ffff\n", color);
4495 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4496 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4498 IDirect3DTexture9_Release(texture);
4499 refcount = IDirect3DDevice9_Release(device);
4500 ok(!refcount, "Device has %u references left.\n", refcount);
4501 done:
4502 IDirect3D9_Release(d3d);
4503 DestroyWindow(window);
4506 static void g16r16_texture_test(void)
4508 IDirect3DTexture9 *texture;
4509 IDirect3DDevice9 *device;
4510 D3DLOCKED_RECT lr;
4511 IDirect3D9 *d3d;
4512 ULONG refcount;
4513 DWORD *data;
4514 DWORD color;
4515 HWND window;
4516 HRESULT hr;
4518 static const float quad[] =
4520 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
4521 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
4522 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
4523 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4526 window = create_window();
4527 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4528 ok(!!d3d, "Failed to create a D3D object.\n");
4529 if (!(device = create_device(d3d, window, window, TRUE)))
4531 skip("Failed to create a D3D device, skipping tests.\n");
4532 goto done;
4535 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
4536 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK)
4538 skip("D3DFMT_G16R16 textures not supported\n");
4539 IDirect3DDevice9_Release(device);
4540 goto done;
4543 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16, D3DPOOL_MANAGED, &texture, NULL);
4544 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
4546 memset(&lr, 0, sizeof(lr));
4547 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4548 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
4549 data = lr.pBits;
4550 *data = 0x0f00f000;
4551 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4552 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
4554 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4555 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4556 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
4557 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4559 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4560 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
4562 hr = IDirect3DDevice9_BeginScene(device);
4563 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4564 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4565 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4566 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4567 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4568 hr = IDirect3DDevice9_EndScene(device);
4569 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4571 color = getPixelColor(device, 240, 320);
4572 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
4573 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
4575 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4576 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4578 IDirect3DTexture9_Release(texture);
4579 refcount = IDirect3DDevice9_Release(device);
4580 ok(!refcount, "Device has %u references left.\n", refcount);
4581 done:
4582 IDirect3D9_Release(d3d);
4583 DestroyWindow(window);
4586 static void check_rect(IDirect3DDevice9 *device, RECT r, const char *message)
4588 LONG x_coords[2][2] =
4590 {r.left - 1, r.left + 1},
4591 {r.right + 1, r.right - 1},
4593 LONG y_coords[2][2] =
4595 {r.top - 1, r.top + 1},
4596 {r.bottom + 1, r.bottom - 1}
4598 unsigned int i, j, x_side, y_side;
4600 for (i = 0; i < 2; ++i)
4602 for (j = 0; j < 2; ++j)
4604 for (x_side = 0; x_side < 2; ++x_side)
4606 for (y_side = 0; y_side < 2; ++y_side)
4608 unsigned int x = x_coords[i][x_side], y = y_coords[j][y_side];
4609 DWORD color;
4610 DWORD expected = (x_side == 1 && y_side == 1) ? 0x00ffffff : 0;
4612 color = getPixelColor(device, x, y);
4613 ok(color == expected, "%s: Pixel (%d, %d) has color %08x, expected %08x\n",
4614 message, x, y, color, expected);
4621 struct projected_textures_test_run
4623 const char *message;
4624 DWORD flags;
4625 IDirect3DVertexDeclaration9 *decl;
4626 BOOL vs, ps;
4627 RECT rect;
4630 static void projected_textures_test(IDirect3DDevice9 *device,
4631 struct projected_textures_test_run tests[4])
4633 unsigned int i;
4635 static const DWORD vertex_shader[] =
4637 0xfffe0101, /* vs_1_1 */
4638 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4639 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
4640 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4641 0x00000001, 0xe00f0000, 0x90e40001, /* mov oT0, v1 */
4642 0x0000ffff /* end */
4644 static const DWORD pixel_shader[] =
4646 0xffff0103, /* ps_1_3 */
4647 0x00000042, 0xb00f0000, /* tex t0 */
4648 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4649 0x0000ffff /* end */
4651 IDirect3DVertexShader9 *vs = NULL;
4652 IDirect3DPixelShader9 *ps = NULL;
4653 IDirect3D9 *d3d;
4654 D3DCAPS9 caps;
4655 HRESULT hr;
4657 IDirect3DDevice9_GetDirect3D(device, &d3d);
4658 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4659 ok(SUCCEEDED(hr), "GetDeviceCaps failed (%08x)\n", hr);
4660 IDirect3D9_Release(d3d);
4662 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
4664 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader, &vs);
4665 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
4667 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 3))
4669 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader, &ps);
4670 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
4673 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0f, 0);
4674 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4676 hr = IDirect3DDevice9_BeginScene(device);
4677 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4679 for (i = 0; i < 4; ++i)
4681 DWORD value = 0xdeadbeef;
4682 static const float proj_quads[] =
4684 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4685 -1.0f, 0.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4686 0.0f, -1.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4687 0.0f, 0.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4689 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4690 0.0f, 0.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4691 1.0f, -1.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4692 1.0f, 0.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4694 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4695 -1.0f, 1.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4696 0.0f, 0.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4697 0.0f, 1.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4699 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4700 0.0f, 1.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4701 1.0f, 0.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4702 1.0f, 1.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4705 if (tests[i].vs)
4707 if (!vs)
4709 skip("Vertex shaders not supported, skipping\n");
4710 continue;
4712 hr = IDirect3DDevice9_SetVertexShader(device, vs);
4714 else
4715 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4716 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
4717 if (tests[i].ps)
4719 if (!ps)
4721 skip("Pixel shaders not supported, skipping\n");
4722 continue;
4724 hr = IDirect3DDevice9_SetPixelShader(device, ps);
4726 else
4727 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4728 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4730 hr = IDirect3DDevice9_SetVertexDeclaration(device, tests[i].decl);
4731 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4733 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, tests[i].flags);
4734 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4735 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, &value);
4736 ok(SUCCEEDED(hr) && value == tests[i].flags,
4737 "GetTextureStageState returned: hr %08x, value %08x.\n", hr, value);
4739 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
4740 &proj_quads[i * 4 * 7], 7 * sizeof(float));
4741 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4744 hr = IDirect3DDevice9_EndScene(device);
4745 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4747 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4748 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4749 if (vs) IDirect3DVertexShader9_Release(vs);
4750 if (ps) IDirect3DPixelShader9_Release(ps);
4752 for (i = 0; i < 4; ++i)
4754 if ((!tests[i].vs || vs) && (!tests[i].ps || ps))
4755 check_rect(device, tests[i].rect, tests[i].message);
4758 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4759 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4762 static void texture_transform_flags_test(void)
4764 HRESULT hr;
4765 IDirect3D9 *d3d;
4766 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
4767 D3DCAPS9 caps;
4768 IDirect3DTexture9 *texture = NULL;
4769 IDirect3DVolumeTexture9 *volume = NULL;
4770 IDirect3DDevice9 *device;
4771 unsigned int x, y, z;
4772 D3DLOCKED_RECT lr;
4773 D3DLOCKED_BOX lb;
4774 D3DCOLOR color;
4775 ULONG refcount;
4776 HWND window;
4777 UINT w, h;
4778 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3, *decl4;
4780 static const D3DVERTEXELEMENT9 decl_elements[] = {
4781 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4782 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4783 D3DDECL_END()
4785 static const D3DVERTEXELEMENT9 decl_elements2[] = {
4786 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4787 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4788 D3DDECL_END()
4790 static const D3DVERTEXELEMENT9 decl_elements3[] = {
4791 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4792 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4793 D3DDECL_END()
4795 static const D3DVERTEXELEMENT9 decl_elements4[] = {
4796 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4797 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4798 D3DDECL_END()
4800 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
4801 0x00, 0xff, 0x00, 0x00,
4802 0x00, 0x00, 0x00, 0x00,
4803 0x00, 0x00, 0x00, 0x00};
4804 static const D3DMATRIX identity =
4806 1.0f, 0.0f, 0.0f, 0.0f,
4807 0.0f, 1.0f, 0.0f, 0.0f,
4808 0.0f, 0.0f, 1.0f, 0.0f,
4809 0.0f, 0.0f, 0.0f, 1.0f,
4810 }}};
4812 window = create_window();
4813 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4814 ok(!!d3d, "Failed to create a D3D object.\n");
4815 if (!(device = create_device(d3d, window, window, TRUE)))
4817 skip("Failed to create a D3D device, skipping tests.\n");
4818 goto done;
4821 memset(&lr, 0, sizeof(lr));
4822 memset(&lb, 0, sizeof(lb));
4823 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
4824 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK)
4825 fmt = D3DFMT_A16B16G16R16;
4827 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4828 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4829 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
4830 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4831 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
4832 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4833 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements4, &decl4);
4834 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4835 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
4836 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
4837 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
4838 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
4839 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
4840 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
4841 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4842 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
4843 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
4844 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
4845 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
4846 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
4847 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
4848 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
4849 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
4850 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState(D3DTSS_COLOROP) returned %08x\n", hr);
4851 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
4852 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState(D3DTSS_COLORARG1) returned %08x\n", hr);
4853 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4854 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
4855 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4856 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4858 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4859 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
4860 w = min(1024, caps.MaxTextureWidth);
4861 h = min(1024, caps.MaxTextureHeight);
4862 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
4863 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
4864 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4865 if (!texture)
4867 skip("Failed to create the test texture.\n");
4868 IDirect3DDevice9_Release(device);
4869 goto done;
4872 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
4873 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
4874 * 1.0 in red and green for the x and y coords
4876 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4877 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
4878 for(y = 0; y < h; y++) {
4879 for(x = 0; x < w; x++) {
4880 double r_f = (double) y / (double) h;
4881 double g_f = (double) x / (double) w;
4882 if(fmt == D3DFMT_A16B16G16R16) {
4883 unsigned short r, g;
4884 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
4885 r = (unsigned short) (r_f * 65536.0);
4886 g = (unsigned short) (g_f * 65536.0);
4887 dst[0] = r;
4888 dst[1] = g;
4889 dst[2] = 0;
4890 dst[3] = 65535;
4891 } else {
4892 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
4893 unsigned char r = (unsigned char) (r_f * 255.0);
4894 unsigned char g = (unsigned char) (g_f * 255.0);
4895 dst[0] = 0;
4896 dst[1] = g;
4897 dst[2] = r;
4898 dst[3] = 255;
4902 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4903 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
4904 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4905 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4907 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4908 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4909 hr = IDirect3DDevice9_BeginScene(device);
4910 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4911 if(SUCCEEDED(hr))
4913 static const float quad1[] =
4915 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f,
4916 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4917 0.0f, -1.0f, 0.1f, 1.0f, 1.0f,
4918 0.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4920 static const float quad2[] =
4922 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4923 -1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4924 0.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4925 0.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4927 static const float quad3[] =
4929 0.0f, 0.0f, 0.1f, 0.5f, 0.5f,
4930 0.0f, 1.0f, 0.1f, 0.5f, 0.5f,
4931 1.0f, 0.0f, 0.1f, 0.5f, 0.5f,
4932 1.0f, 1.0f, 0.1f, 0.5f, 0.5f,
4934 static const float quad4[] =
4936 320.0f, 480.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4937 320.0f, 240.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4938 640.0f, 480.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4939 640.0f, 240.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4941 D3DMATRIX mat =
4943 0.0f, 0.0f, 0.0f, 0.0f,
4944 0.0f, 0.0f, 0.0f, 0.0f,
4945 0.0f, 0.0f, 0.0f, 0.0f,
4946 0.0f, 0.0f, 0.0f, 0.0f,
4947 }}};
4949 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
4950 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4951 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4952 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4953 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4955 /* What happens with transforms enabled? */
4956 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4957 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4958 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4959 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4961 /* What happens if 4 coords are used, but only 2 given ?*/
4962 U(mat).m[2][0] = 1.0f;
4963 U(mat).m[3][1] = 1.0f;
4964 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4965 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4966 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
4967 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4968 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4969 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4971 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
4972 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
4973 * due to the coords in the vertices. (turns out red, indeed)
4975 memset(&mat, 0, sizeof(mat));
4976 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4977 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4978 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
4979 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4980 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4981 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4982 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4983 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4985 hr = IDirect3DDevice9_EndScene(device);
4986 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4988 color = getPixelColor(device, 160, 360);
4989 ok(color_match(color, 0x00ffff00, 1), "quad 1 has color %08x, expected 0x00ffff00\n", color);
4990 color = getPixelColor(device, 160, 120);
4991 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4992 color = getPixelColor(device, 480, 120);
4993 ok(color_match(color, 0x0000ff00, 1), "quad 3 has color %08x, expected 0x0000ff00\n", color);
4994 color = getPixelColor(device, 480, 360);
4995 ok(color_match(color, 0x00ff0000, 1), "quad 4 has color %08x, expected 0x00ff0000\n", color);
4996 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4997 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4999 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
5000 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5002 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5003 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5004 hr = IDirect3DDevice9_BeginScene(device);
5005 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
5006 if(SUCCEEDED(hr))
5008 static const float quad1[] =
5010 -1.0f, -1.0f, 0.1f, 0.8f, 0.2f,
5011 -1.0f, 0.0f, 0.1f, 0.8f, 0.2f,
5012 0.0f, -1.0f, 0.1f, 0.8f, 0.2f,
5013 0.0f, 0.0f, 0.1f, 0.8f, 0.2f,
5015 static const float quad2[] =
5017 -1.0f, 0.0f, 0.1f, 0.5f, 1.0f,
5018 -1.0f, 1.0f, 0.1f, 0.5f, 1.0f,
5019 0.0f, 0.0f, 0.1f, 0.5f, 1.0f,
5020 0.0f, 1.0f, 0.1f, 0.5f, 1.0f,
5022 static const float quad3[] =
5024 0.0f, 0.0f, 0.1f, 0.5f, 1.0f,
5025 0.0f, 1.0f, 0.1f, 0.5f, 1.0f,
5026 1.0f, 0.0f, 0.1f, 0.5f, 1.0f,
5027 1.0f, 1.0f, 0.1f, 0.5f, 1.0f,
5029 static const float quad4[] =
5031 0.0f, -1.0f, 0.1f, 0.8f, 0.2f,
5032 0.0f, 0.0f, 0.1f, 0.8f, 0.2f,
5033 1.0f, -1.0f, 0.1f, 0.8f, 0.2f,
5034 1.0f, 0.0f, 0.1f, 0.8f, 0.2f,
5036 D3DMATRIX mat =
5038 0.0f, 0.0f, 0.0f, 0.0f,
5039 0.0f, 0.0f, 0.0f, 0.0f,
5040 0.0f, 1.0f, 0.0f, 0.0f,
5041 0.0f, 0.0f, 0.0f, 0.0f,
5042 }}};
5044 /* What happens to the default 1 in the 3rd coordinate if it is disabled? */
5045 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5046 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5047 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
5048 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5050 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
5051 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
5053 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
5054 * it behaves like COUNT2 because normal textures require 2 coords. */
5055 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
5056 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5057 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
5058 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
5060 /* Just to be sure, the same as quad2 above */
5061 memset(&mat, 0, sizeof(mat));
5062 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5063 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5064 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
5065 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5066 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
5067 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
5069 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
5070 * used? And what happens to the first? */
5071 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
5072 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5073 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
5074 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
5076 hr = IDirect3DDevice9_EndScene(device);
5077 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
5079 color = getPixelColor(device, 160, 360);
5080 ok(color_match(color, 0x00ff0000, 1), "quad 1 has color %08x, expected 0x00ff0000\n", color);
5081 color = getPixelColor(device, 160, 120);
5082 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
5083 color = getPixelColor(device, 480, 120);
5084 ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
5085 "quad 3 has color %08x, expected 0x00ff8000\n", color);
5086 color = getPixelColor(device, 480, 360);
5087 ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00ff0000, 1),
5088 "quad 4 has color %08x, expected 0x0033cc00\n", color);
5089 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5090 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5092 IDirect3DTexture9_Release(texture);
5094 /* Test projected textures, without any fancy matrices */
5095 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
5096 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5097 if (SUCCEEDED(hr))
5099 struct projected_textures_test_run projected_tests_1[4] =
5102 "D3DTTFF_COUNT4 | D3DTTFF_PROJECTED - bottom left",
5103 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED,
5104 decl3,
5105 FALSE, TRUE,
5106 {120, 300, 240, 390},
5109 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED - bottom right",
5110 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
5111 decl3,
5112 FALSE, TRUE,
5113 {400, 360, 480, 420},
5115 /* Try with some invalid values */
5117 "0xffffffff (draws like COUNT4 | PROJECTED) - top left",
5118 0xffffffff,
5119 decl3,
5120 FALSE, TRUE,
5121 {120, 60, 240, 150}
5124 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (draws non-projected) - top right",
5125 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
5126 decl4,
5127 FALSE, TRUE,
5128 {340, 210, 360, 225},
5131 struct projected_textures_test_run projected_tests_2[4] =
5134 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED, texcoord has 4 components) - bottom left",
5135 D3DTTFF_PROJECTED,
5136 decl3,
5137 FALSE, TRUE,
5138 {120, 300, 240, 390},
5141 "D3DTTFF_PROJECTED (like COUNT3 | PROJECTED, texcoord has only 3 components) - bottom right",
5142 D3DTTFF_PROJECTED,
5143 decl,
5144 FALSE, TRUE,
5145 {400, 360, 480, 420},
5148 "0xffffffff (like COUNT3 | PROJECTED, texcoord has only 3 components) - top left",
5149 0xffffffff,
5150 decl,
5151 FALSE, TRUE,
5152 {80, 120, 160, 180},
5155 "D3DTTFF_COUNT1 (draws non-projected) - top right",
5156 D3DTTFF_COUNT1,
5157 decl4,
5158 FALSE, TRUE,
5159 {340, 210, 360, 225},
5162 struct projected_textures_test_run projected_tests_3[4] =
5165 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom left",
5166 D3DTTFF_PROJECTED,
5167 decl3,
5168 TRUE, FALSE,
5169 {120, 300, 240, 390},
5172 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom right",
5173 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
5174 decl3,
5175 TRUE, TRUE,
5176 {440, 300, 560, 390},
5179 "0xffffffff (like COUNT4 | PROJECTED) - top left",
5180 0xffffffff,
5181 decl3,
5182 TRUE, TRUE,
5183 {120, 60, 240, 150},
5186 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - top right",
5187 D3DTTFF_PROJECTED,
5188 decl3,
5189 FALSE, FALSE,
5190 {440, 60, 560, 150},
5194 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
5195 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5197 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5198 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
5199 for(x = 0; x < 4; x++) {
5200 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
5202 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5203 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
5204 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5205 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
5207 projected_textures_test(device, projected_tests_1);
5208 projected_textures_test(device, projected_tests_2);
5209 projected_textures_test(device, projected_tests_3);
5211 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5212 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
5213 IDirect3DTexture9_Release(texture);
5216 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
5217 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5218 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
5219 * Thus watch out if sampling from texels between 0 and 1.
5221 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
5222 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
5223 "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
5224 if(!volume) {
5225 skip("Failed to create a volume texture\n");
5226 goto out;
5229 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
5230 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
5231 for(z = 0; z < 32; z++) {
5232 for(y = 0; y < 32; y++) {
5233 for(x = 0; x < 32; x++) {
5234 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
5235 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
5236 float r_f = (float) x / 31.0;
5237 float g_f = (float) y / 31.0;
5238 float b_f = (float) z / 31.0;
5240 if(fmt == D3DFMT_A16B16G16R16) {
5241 unsigned short *mem_s = mem;
5242 mem_s[0] = r_f * 65535.0;
5243 mem_s[1] = g_f * 65535.0;
5244 mem_s[2] = b_f * 65535.0;
5245 mem_s[3] = 65535;
5246 } else {
5247 unsigned char *mem_c = mem;
5248 mem_c[0] = b_f * 255.0;
5249 mem_c[1] = g_f * 255.0;
5250 mem_c[2] = r_f * 255.0;
5251 mem_c[3] = 255;
5256 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
5257 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
5259 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
5260 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
5262 hr = IDirect3DDevice9_BeginScene(device);
5263 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
5264 if(SUCCEEDED(hr))
5266 static const float quad1[] =
5268 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5269 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5270 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5271 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5273 static const float quad2[] =
5275 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5276 -1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5277 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5278 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5280 static const float quad3[] =
5282 0.0f, 0.0f, 0.1f, 0.0f, 0.0f,
5283 0.0f, 1.0f, 0.1f, 0.0f, 0.0f,
5284 1.0f, 0.0f, 0.1f, 0.0f, 0.0f,
5285 1.0f, 1.0f, 0.1f, 0.0f, 0.0f,
5287 static const float quad4[] =
5289 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5290 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5291 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5292 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5294 D3DMATRIX mat =
5296 1.0f, 0.0f, 0.0f, 0.0f,
5297 0.0f, 0.0f, 1.0f, 0.0f,
5298 0.0f, 1.0f, 0.0f, 0.0f,
5299 0.0f, 0.0f, 0.0f, 1.0f,
5300 }}};
5301 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5302 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5304 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
5305 * values
5307 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5308 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5309 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
5310 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5311 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5312 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5314 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
5315 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
5316 * otherwise the w will be missing(blue).
5317 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
5318 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3. */
5319 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
5320 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5321 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5322 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5324 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
5325 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
5326 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5327 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
5328 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5329 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5330 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5331 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
5332 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5334 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
5335 * disable. ATI extends it up to the amount of values needed for the volume texture
5337 memset(&mat, 0, sizeof(mat));
5338 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5339 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5340 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
5341 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5342 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5343 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5344 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5345 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5347 hr = IDirect3DDevice9_EndScene(device);
5348 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
5351 color = getPixelColor(device, 160, 360);
5352 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
5353 color = getPixelColor(device, 160, 120);
5354 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
5355 "quad 2 has color %08x, expected 0x00ffff00\n", color);
5356 color = getPixelColor(device, 480, 120);
5357 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
5358 color = getPixelColor(device, 480, 360);
5359 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
5361 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5362 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5364 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
5365 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5366 hr = IDirect3DDevice9_BeginScene(device);
5367 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
5368 if(SUCCEEDED(hr))
5370 static const float quad1[] =
5372 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5373 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5374 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5375 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5377 static const float quad2[] =
5379 -1.0f, 0.0f, 0.1f,
5380 -1.0f, 1.0f, 0.1f,
5381 0.0f, 0.0f, 0.1f,
5382 0.0f, 1.0f, 0.1f,
5384 static const float quad3[] =
5386 0.0f, 0.0f, 0.1f, 1.0f,
5387 0.0f, 1.0f, 0.1f, 1.0f,
5388 1.0f, 0.0f, 0.1f, 1.0f,
5389 1.0f, 1.0f, 0.1f, 1.0f,
5391 static const D3DMATRIX mat =
5393 0.0f, 0.0f, 0.0f, 0.0f,
5394 0.0f, 0.0f, 0.0f, 0.0f,
5395 0.0f, 0.0f, 0.0f, 0.0f,
5396 0.0f, 1.0f, 0.0f, 0.0f,
5397 }}};
5398 static const D3DMATRIX mat2 =
5400 0.0f, 0.0f, 0.0f, 1.0f,
5401 1.0f, 0.0f, 0.0f, 0.0f,
5402 0.0f, 1.0f, 0.0f, 0.0f,
5403 0.0f, 0.0f, 1.0f, 0.0f,
5404 }}};
5405 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5406 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5408 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
5409 * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
5410 * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
5411 * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
5412 * 4th *input* coordinate.
5414 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5415 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5416 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
5417 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5418 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5419 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5421 /* None passed */
5422 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
5423 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5424 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5425 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5426 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5427 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5429 /* 4 used, 1 passed */
5430 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5431 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5432 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat2);
5433 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5434 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
5435 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5437 hr = IDirect3DDevice9_EndScene(device);
5438 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
5440 color = getPixelColor(device, 160, 360);
5441 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
5442 color = getPixelColor(device, 160, 120);
5443 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
5444 color = getPixelColor(device, 480, 120);
5445 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
5446 /* Quad4: unused */
5448 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5449 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5451 IDirect3DVolumeTexture9_Release(volume);
5453 out:
5454 IDirect3DVertexDeclaration9_Release(decl);
5455 IDirect3DVertexDeclaration9_Release(decl2);
5456 IDirect3DVertexDeclaration9_Release(decl3);
5457 IDirect3DVertexDeclaration9_Release(decl4);
5458 refcount = IDirect3DDevice9_Release(device);
5459 ok(!refcount, "Device has %u references left.\n", refcount);
5460 done:
5461 IDirect3D9_Release(d3d);
5462 DestroyWindow(window);
5465 static void texdepth_test(void)
5467 IDirect3DPixelShader9 *shader;
5468 IDirect3DDevice9 *device;
5469 IDirect3D9 *d3d;
5470 ULONG refcount;
5471 D3DCAPS9 caps;
5472 DWORD color;
5473 HWND window;
5474 HRESULT hr;
5476 static const float texdepth_test_data1[] = { 0.25f, 2.0f, 0.0f, 0.0f};
5477 static const float texdepth_test_data2[] = { 0.25f, 0.5f, 0.0f, 0.0f};
5478 static const float texdepth_test_data3[] = {-1.00f, 0.1f, 0.0f, 0.0f};
5479 static const float texdepth_test_data4[] = {-0.25f, -0.5f, 0.0f, 0.0f};
5480 static const float texdepth_test_data5[] = { 1.00f, -0.1f, 0.0f, 0.0f};
5481 static const float texdepth_test_data6[] = { 1.00f, 0.5f, 0.0f, 0.0f};
5482 static const float texdepth_test_data7[] = { 0.50f, 0.0f, 0.0f, 0.0f};
5483 static const DWORD shader_code[] =
5485 0xffff0104, /* ps_1_4 */
5486 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
5487 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
5488 0x0000fffd, /* phase */
5489 0x00000057, 0x800f0005, /* texdepth r5 */
5490 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
5491 0x0000ffff /* end */
5493 static const float vertex[] =
5495 -1.0f, -1.0f, 0.0f,
5496 -1.0f, 1.0f, 0.0f,
5497 1.0f, -1.0f, 1.0f,
5498 1.0f, 1.0f, 1.0f,
5501 window = create_window();
5502 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5503 ok(!!d3d, "Failed to create a D3D object.\n");
5504 if (!(device = create_device(d3d, window, window, TRUE)))
5506 skip("Failed to create a D3D device, skipping tests.\n");
5507 goto done;
5510 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5511 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5512 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
5514 skip("No ps_1_4 support, skipping tests.\n");
5515 IDirect3DDevice9_Release(device);
5516 goto done;
5519 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5520 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5522 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
5523 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5524 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5525 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
5526 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
5527 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5528 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
5529 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5530 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
5531 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5532 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5533 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
5535 /* Fill the depth buffer with a gradient */
5536 hr = IDirect3DDevice9_BeginScene(device);
5537 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5538 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5539 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5540 hr = IDirect3DDevice9_EndScene(device);
5541 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5543 /* Now perform the actual tests. Same geometry, but with the shader */
5544 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
5545 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5546 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
5547 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5548 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5549 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5551 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
5552 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5553 hr = IDirect3DDevice9_BeginScene(device);
5554 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5555 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5556 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5557 hr = IDirect3DDevice9_EndScene(device);
5558 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5560 color = getPixelColor(device, 158, 240);
5561 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
5562 color = getPixelColor(device, 162, 240);
5563 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
5565 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5566 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5568 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5569 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5571 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
5572 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5573 hr = IDirect3DDevice9_BeginScene(device);
5574 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5575 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5576 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5577 hr = IDirect3DDevice9_EndScene(device);
5578 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5580 color = getPixelColor(device, 318, 240);
5581 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
5582 color = getPixelColor(device, 322, 240);
5583 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
5585 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5586 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5588 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
5589 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5591 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
5592 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5593 hr = IDirect3DDevice9_BeginScene(device);
5594 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5595 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5596 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5597 hr = IDirect3DDevice9_EndScene(device);
5598 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5600 color = getPixelColor(device, 1, 240);
5601 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
5603 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5604 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5606 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
5607 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5609 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
5610 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5611 hr = IDirect3DDevice9_BeginScene(device);
5612 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5613 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * 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, 318, 240);
5619 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
5620 color = getPixelColor(device, 322, 240);
5621 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
5623 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5624 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5626 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5627 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5629 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
5630 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5631 hr = IDirect3DDevice9_BeginScene(device);
5632 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5633 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5634 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5635 hr = IDirect3DDevice9_EndScene(device);
5636 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5638 color = getPixelColor(device, 1, 240);
5639 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
5641 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5642 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5644 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
5645 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5647 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
5648 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5649 hr = IDirect3DDevice9_BeginScene(device);
5650 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5651 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5652 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5653 hr = IDirect3DDevice9_EndScene(device);
5654 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5656 color = getPixelColor(device, 638, 240);
5657 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
5659 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5660 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5662 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
5663 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5665 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
5666 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5667 hr = IDirect3DDevice9_BeginScene(device);
5668 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5669 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5670 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5671 hr = IDirect3DDevice9_EndScene(device);
5672 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5674 color = getPixelColor(device, 638, 240);
5675 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
5677 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5678 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5680 IDirect3DPixelShader9_Release(shader);
5681 refcount = IDirect3DDevice9_Release(device);
5682 ok(!refcount, "Device has %u references left.\n", refcount);
5683 done:
5684 IDirect3D9_Release(d3d);
5685 DestroyWindow(window);
5688 static void texkill_test(void)
5690 IDirect3DPixelShader9 *shader;
5691 IDirect3DDevice9 *device;
5692 IDirect3D9 *d3d;
5693 ULONG refcount;
5694 D3DCAPS9 caps;
5695 DWORD color;
5696 HWND window;
5697 HRESULT hr;
5699 static const float vertex[] =
5701 /* bottom top right left */
5702 -1.0f, -1.0f, 1.0f, -0.1f, 0.9f, 0.9f, -0.1f,
5703 -1.0f, 1.0f, 1.0f, -0.1f, 0.9f, -0.1f, 0.9f,
5704 1.0f, -1.0f, 0.0f, 0.9f, -0.1f, 0.9f, -0.1f,
5705 1.0f, 1.0f, 0.0f, 0.9f, -0.1f, -0.1f, 0.9f,
5707 static const DWORD shader_code_11[] =
5709 0xffff0101, /* ps_1_1 */
5710 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
5711 0x00000041, 0xb00f0000, /* texkill t0 */
5712 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5713 0x0000ffff /* end */
5715 static const DWORD shader_code_20[] =
5717 0xffff0200, /* ps_2_0 */
5718 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
5719 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
5720 0x01000041, 0xb00f0000, /* texkill t0 */
5721 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
5722 0x0000ffff /* end */
5725 window = create_window();
5726 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5727 ok(!!d3d, "Failed to create a D3D object.\n");
5728 if (!(device = create_device(d3d, window, window, TRUE)))
5730 skip("Failed to create a D3D device, skipping tests.\n");
5731 goto done;
5734 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5735 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5736 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
5738 skip("No ps_1_1 support, skipping tests.\n");
5739 IDirect3DDevice9_Release(device);
5740 goto done;
5743 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
5744 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5745 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
5746 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5748 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5749 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5750 hr = IDirect3DDevice9_BeginScene(device);
5751 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5752 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
5753 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5754 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
5755 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5756 hr = IDirect3DDevice9_EndScene(device);
5757 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5759 color = getPixelColor(device, 63, 46);
5760 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
5761 color = getPixelColor(device, 66, 46);
5762 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
5763 color = getPixelColor(device, 63, 49);
5764 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
5765 color = getPixelColor(device, 66, 49);
5766 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
5768 color = getPixelColor(device, 578, 46);
5769 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5770 color = getPixelColor(device, 575, 46);
5771 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5772 color = getPixelColor(device, 578, 49);
5773 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
5774 color = getPixelColor(device, 575, 49);
5775 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5777 color = getPixelColor(device, 63, 430);
5778 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5779 color = getPixelColor(device, 63, 433);
5780 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5781 color = getPixelColor(device, 66, 433);
5782 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
5783 color = getPixelColor(device, 66, 430);
5784 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5786 color = getPixelColor(device, 578, 430);
5787 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5788 color = getPixelColor(device, 578, 433);
5789 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5790 color = getPixelColor(device, 575, 433);
5791 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
5792 color = getPixelColor(device, 575, 430);
5793 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5795 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5796 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5798 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5799 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5800 IDirect3DPixelShader9_Release(shader);
5802 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5803 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5804 if (FAILED(IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader)))
5806 skip("Failed to create 2.0 test shader, most likely not supported.\n");
5807 IDirect3DDevice9_Release(device);
5808 goto done;
5811 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5812 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5813 hr = IDirect3DDevice9_BeginScene(device);
5814 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5815 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
5816 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5817 hr = IDirect3DDevice9_EndScene(device);
5818 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5820 color = getPixelColor(device, 63, 46);
5821 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
5822 color = getPixelColor(device, 66, 46);
5823 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
5824 color = getPixelColor(device, 63, 49);
5825 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
5826 color = getPixelColor(device, 66, 49);
5827 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
5829 color = getPixelColor(device, 578, 46);
5830 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5831 color = getPixelColor(device, 575, 46);
5832 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5833 color = getPixelColor(device, 578, 49);
5834 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5835 color = getPixelColor(device, 575, 49);
5836 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5838 color = getPixelColor(device, 63, 430);
5839 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5840 color = getPixelColor(device, 63, 433);
5841 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5842 color = getPixelColor(device, 66, 433);
5843 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5844 color = getPixelColor(device, 66, 430);
5845 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5847 color = getPixelColor(device, 578, 430);
5848 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5849 color = getPixelColor(device, 578, 433);
5850 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5851 color = getPixelColor(device, 575, 433);
5852 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5853 color = getPixelColor(device, 575, 430);
5854 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5856 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5857 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5859 IDirect3DPixelShader9_Release(shader);
5860 refcount = IDirect3DDevice9_Release(device);
5861 ok(!refcount, "Device has %u references left.\n", refcount);
5862 done:
5863 IDirect3D9_Release(d3d);
5864 DestroyWindow(window);
5867 static void test_mipmap_autogen(void)
5869 IDirect3DSurface9 *surface, *surface2, *surface3, *backbuffer;
5870 IDirect3DTexture9 *texture, *texture2, *texture3;
5871 IDirect3DCubeTexture9 *cube_texture;
5872 IDirect3DDevice9 *device;
5873 unsigned int i, x, y;
5874 D3DLOCKED_RECT lr;
5875 IDirect3D9 *d3d;
5876 D3DCOLOR color;
5877 ULONG refcount;
5878 D3DCAPS9 caps;
5879 HWND window;
5880 HRESULT hr;
5882 static const RECT r1 = {256, 256, 512, 512};
5883 static const RECT r2 = {512, 256, 768, 512};
5884 static const RECT r3 = {256, 512, 512, 768};
5885 static const RECT r4 = {512, 512, 768, 768};
5886 static const float quad[] =
5888 -0.5f, -0.5f, 0.1f, 0.0f, 0.0f,
5889 -0.5f, 0.5f, 0.1f, 0.0f, 1.0f,
5890 0.5f, -0.5f, 0.1f, 1.0f, 0.0f,
5891 0.5f, 0.5f, 0.1f, 1.0f, 1.0f,
5894 window = create_window();
5895 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5896 ok(!!d3d, "Failed to create a D3D object.\n");
5897 if (!(device = create_device(d3d, window, window, TRUE)))
5899 skip("Failed to create a D3D device, skipping tests.\n");
5900 goto done;
5903 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
5904 D3DFMT_X8R8G8B8, D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK)
5906 skip("No autogenmipmap support.\n");
5907 IDirect3DDevice9_Release(device);
5908 goto done;
5911 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
5912 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
5914 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 1.0f, 0);
5915 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5917 /* Make the texture big enough that a mipmap level > 0 is used. */
5918 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
5919 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
5920 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5922 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5923 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
5924 memset(&lr, 0, sizeof(lr));
5925 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5926 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
5927 for(y = 0; y < 1024; y++) {
5928 for(x = 0; x < 1024; x++) {
5929 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
5930 POINT pt;
5932 pt.x = x;
5933 pt.y = y;
5934 if(PtInRect(&r1, pt)) {
5935 *dst = 0xffff0000;
5936 } else if(PtInRect(&r2, pt)) {
5937 *dst = 0xff00ff00;
5938 } else if(PtInRect(&r3, pt)) {
5939 *dst = 0xff0000ff;
5940 } else if(PtInRect(&r4, pt)) {
5941 *dst = 0xff000000;
5942 } else {
5943 *dst = 0xffffffff;
5947 hr = IDirect3DSurface9_UnlockRect(surface);
5948 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
5949 IDirect3DSurface9_Release(surface);
5951 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5952 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5953 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
5954 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
5955 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5956 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
5958 hr = IDirect3DDevice9_BeginScene(device);
5959 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5960 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5961 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5962 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5963 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5964 hr = IDirect3DDevice9_EndScene(device);
5965 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5966 IDirect3DTexture9_Release(texture);
5968 color = getPixelColor(device, 200, 200);
5969 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
5970 color = getPixelColor(device, 280, 200);
5971 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
5972 color = getPixelColor(device, 360, 200);
5973 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
5974 color = getPixelColor(device, 440, 200);
5975 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5976 color = getPixelColor(device, 200, 270);
5977 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
5978 color = getPixelColor(device, 280, 270);
5979 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
5980 color = getPixelColor(device, 360, 270);
5981 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
5982 color = getPixelColor(device, 440, 270);
5983 ok(color == 0x00ffffff, "pixel 440/270 has color %08x, expected 0x00ffffff\n", color);
5984 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5985 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5987 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5988 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5989 if (!(caps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES))
5991 skip("Blitting from textures is not supported.\n");
5992 IDirect3DSurface9_Release(backbuffer);
5993 IDirect3DDevice9_Release(device);
5994 goto done;
5996 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1, 0,
5997 D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, 0);
5998 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5999 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
6000 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture2, 0);
6001 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
6002 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP | D3DUSAGE_RENDERTARGET,
6003 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture3, 0);
6004 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
6006 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6007 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x.\n", hr);
6008 memset(&lr, 0, sizeof(lr));
6009 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
6010 ok(SUCCEEDED(hr), "Failed to map surface, hr %#x.\n", hr);
6011 for (y = 0; y < 1024; ++y)
6013 for (x = 0; x < 1024; ++x)
6015 DWORD *dst = (DWORD *)((BYTE *)lr.pBits + y * lr.Pitch + x * 4);
6016 POINT pt;
6018 pt.x = x;
6019 pt.y = y;
6020 if (PtInRect(&r1, pt))
6021 *dst = 0xffff0000;
6022 else if (PtInRect(&r2, pt))
6023 *dst = 0xff00ff00;
6024 else if (PtInRect(&r3, pt))
6025 *dst = 0xff0000ff;
6026 else if (PtInRect(&r4, pt))
6027 *dst = 0xff000000;
6028 else
6029 *dst = 0xffffffff;
6032 hr = IDirect3DSurface9_UnlockRect(surface);
6033 ok(SUCCEEDED(hr), "Failed to unmap surface, hr %#x.\n", hr);
6034 IDirect3DSurface9_Release(surface);
6036 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture,
6037 (IDirect3DBaseTexture9 *)texture2);
6038 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
6040 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture2);
6041 ok(SUCCEEDED(hr), "Failed to set texture, hr %x.\n", hr);
6043 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 1.0f, 0);
6044 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6046 hr = IDirect3DDevice9_BeginScene(device);
6047 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6048 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6049 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6050 hr = IDirect3DDevice9_EndScene(device);
6051 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6053 color = getPixelColor(device, 200, 200);
6054 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6055 color = getPixelColor(device, 280, 200);
6056 ok(color == 0x000000ff, "Unexpected color 0x%08x.\n", color);
6057 color = getPixelColor(device, 360, 200);
6058 ok(color == 0x00000000, "Unexpected color 0x%08x.\n", color);
6059 color = getPixelColor(device, 440, 200);
6060 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6061 color = getPixelColor(device, 200, 270);
6062 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6063 color = getPixelColor(device, 280, 270);
6064 ok(color == 0x00ff0000, "Unexpected color 0x%08x.\n", color);
6065 color = getPixelColor(device, 360, 270);
6066 ok(color == 0x0000ff00, "Unexpected color 0x%08x.\n", color);
6067 color = getPixelColor(device, 440, 270);
6068 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6070 hr = IDirect3DTexture9_GetSurfaceLevel(texture2, 0, &surface2);
6071 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x.\n", hr);
6072 hr = IDirect3DTexture9_GetSurfaceLevel(texture3, 0, &surface3);
6073 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x.\n", hr);
6074 hr = IDirect3DDevice9_StretchRect(device, surface2, NULL, surface3, NULL, D3DTEXF_POINT);
6075 ok(SUCCEEDED(hr), "Failed to blit texture, hr %#x.\n", hr);
6077 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture3);
6078 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
6080 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 1.0f, 0);
6081 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6083 hr = IDirect3DDevice9_BeginScene(device);
6084 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6085 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6086 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6087 hr = IDirect3DDevice9_EndScene(device);
6088 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6090 color = getPixelColor(device, 200, 200);
6091 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6092 color = getPixelColor(device, 280, 200);
6093 ok(color == 0x000000ff, "Unexpected color 0x%08x.\n", color);
6094 color = getPixelColor(device, 360, 200);
6095 ok(color == 0x00000000, "Unexpected color 0x%08x.\n", color);
6096 color = getPixelColor(device, 440, 200);
6097 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6098 color = getPixelColor(device, 200, 270);
6099 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6100 color = getPixelColor(device, 280, 270);
6101 ok(color == 0x00ff0000, "Unexpected color 0x%08x.\n", color);
6102 color = getPixelColor(device, 360, 270);
6103 ok(color == 0x0000ff00, "Unexpected color 0x%08x.\n", color);
6104 color = getPixelColor(device, 440, 270);
6105 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6107 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface3);
6108 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
6110 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 1.0f, 0);
6111 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6113 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6114 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
6116 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 1.0f, 0);
6117 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6119 hr = IDirect3DDevice9_BeginScene(device);
6120 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6121 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6122 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6123 hr = IDirect3DDevice9_EndScene(device);
6124 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6126 color = getPixelColor(device, 200, 200);
6127 ok(color == 0x0000ffff, "Unexpected color 0x%08x.\n", color);
6129 IDirect3DSurface9_Release(surface3);
6130 IDirect3DSurface9_Release(surface2);
6131 IDirect3DTexture9_Release(texture3);
6132 IDirect3DTexture9_Release(texture2);
6133 IDirect3DTexture9_Release(texture);
6135 if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP))
6137 skip("No cube textures support.\n");
6138 IDirect3DSurface9_Release(backbuffer);
6139 IDirect3DDevice9_Release(device);
6140 goto done;
6142 hr = IDirect3DDevice9_CreateCubeTexture(device, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
6143 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &cube_texture, 0);
6144 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
6145 for (i = 0; i < 6; ++i)
6147 hr = IDirect3DCubeTexture9_LockRect(cube_texture, i, 0, &lr, NULL, 0);
6148 ok(SUCCEEDED(hr), "Failed to map texture, hr %#x.\n", hr);
6150 for (y = 0; y < 1024; ++y)
6152 for (x = 0; x < 1024; ++x)
6154 DWORD *dst = (DWORD *)((BYTE *)lr.pBits + y * lr.Pitch + x * 4);
6155 POINT pt;
6157 pt.x = x;
6158 pt.y = y;
6159 if (PtInRect(&r1, pt))
6160 *dst = 0xffff0000;
6161 else if (PtInRect(&r2, pt))
6162 *dst = 0xff00ff00;
6163 else if (PtInRect(&r3, pt))
6164 *dst = 0xff0000ff;
6165 else if (PtInRect(&r4, pt))
6166 *dst = 0xff000000;
6167 else
6168 *dst = 0xffffffff;
6171 hr = IDirect3DCubeTexture9_UnlockRect(cube_texture, i, 0);
6172 ok(SUCCEEDED(hr), "Failed to unmap texture, hr %#x.\n", hr);
6175 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)cube_texture);
6176 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
6178 hr = IDirect3DDevice9_BeginScene(device);
6179 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6180 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6181 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
6182 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6183 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6184 hr = IDirect3DDevice9_EndScene(device);
6185 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6186 IDirect3DCubeTexture9_Release(cube_texture);
6188 color = getPixelColor(device, 200, 200);
6189 ok(color == 0x00000000, "Unexpected color 0x%08x.\n", color);
6190 color = getPixelColor(device, 280, 200);
6191 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6192 color = getPixelColor(device, 360, 200);
6193 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6194 color = getPixelColor(device, 440, 200);
6195 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6196 color = getPixelColor(device, 200, 270);
6197 ok(color == 0x00000000, "Unexpected color 0x%08x.\n", color);
6198 color = getPixelColor(device, 280, 270);
6199 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6200 color = getPixelColor(device, 360, 270);
6201 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6202 color = getPixelColor(device, 440, 270);
6203 ok(color == 0x0000ff00, "Unexpected color 0x%08x.\n", color);
6205 IDirect3DSurface9_Release(backbuffer);
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 test_constant_clamp_vs(void)
6216 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
6217 IDirect3DVertexDeclaration9 *decl;
6218 IDirect3DDevice9 *device;
6219 IDirect3D9 *d3d;
6220 D3DCOLOR color;
6221 ULONG refcount;
6222 D3DCAPS9 caps;
6223 HWND window;
6224 HRESULT hr;
6226 static const DWORD shader_code_11[] =
6228 0xfffe0101, /* vs_1_1 */
6229 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6230 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6231 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
6232 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6233 0x0000ffff /* end */
6235 static const DWORD shader_code_11_2[] =
6237 0xfffe0101, /* vs_1_1 */
6238 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
6239 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
6240 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6241 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6242 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
6243 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6244 0x0000ffff /* end */
6246 static const DWORD shader_code_20[] =
6248 0xfffe0200, /* vs_2_0 */
6249 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6250 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6251 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
6252 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6253 0x0000ffff /* end */
6255 static const DWORD shader_code_20_2[] =
6257 0xfffe0200, /* vs_2_0 */
6258 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
6259 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
6260 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6261 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6262 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
6263 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6264 0x0000ffff /* end */
6266 static const D3DVERTEXELEMENT9 decl_elements[] =
6268 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6269 D3DDECL_END()
6271 static const float quad1[] =
6273 -1.0f, -1.0f, 0.1f,
6274 -1.0f, 0.0f, 0.1f,
6275 0.0f, -1.0f, 0.1f,
6276 0.0f, 0.0f, 0.1f,
6278 static const float quad2[] =
6280 0.0f, -1.0f, 0.1f,
6281 0.0f, 0.0f, 0.1f,
6282 1.0f, -1.0f, 0.1f,
6283 1.0f, 0.0f, 0.1f,
6285 static const float quad3[] =
6287 0.0f, 0.0f, 0.1f,
6288 0.0f, 1.0f, 0.1f,
6289 1.0f, 0.0f, 0.1f,
6290 1.0f, 1.0f, 0.1f,
6292 static const float quad4[] =
6294 -1.0f, 0.0f, 0.1f,
6295 -1.0f, 1.0f, 0.1f,
6296 0.0f, 0.0f, 0.1f,
6297 0.0f, 1.0f, 0.1f,
6299 static const float test_data_c1[4] = { 1.25f, -0.50f, -1.50f, 1.0f};
6300 static const float test_data_c2[4] = {-0.50f, 1.25f, 2.00f, 1.0f};
6302 window = create_window();
6303 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6304 ok(!!d3d, "Failed to create a D3D object.\n");
6305 if (!(device = create_device(d3d, window, window, TRUE)))
6307 skip("Failed to create a D3D device, skipping tests.\n");
6308 goto done;
6311 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6312 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6313 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
6315 skip("No vs_1_1 support, skipping tests.\n");
6316 IDirect3DDevice9_Release(device);
6317 goto done;
6320 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
6321 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6323 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
6324 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6325 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
6326 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6327 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
6328 if(FAILED(hr)) shader_20 = NULL;
6329 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
6330 if(FAILED(hr)) shader_20_2 = NULL;
6331 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
6332 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6334 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
6335 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
6336 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
6337 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
6338 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6339 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6341 hr = IDirect3DDevice9_BeginScene(device);
6342 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6344 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
6345 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
6346 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
6347 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6349 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
6350 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
6351 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
6352 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6354 if (shader_20)
6356 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
6357 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
6358 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
6359 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6362 if (shader_20_2)
6364 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
6365 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
6366 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
6367 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6370 hr = IDirect3DDevice9_EndScene(device);
6371 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6373 color = getPixelColor(device, 160, 360);
6374 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6375 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
6376 color = getPixelColor(device, 480, 360);
6377 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6378 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
6379 if(shader_20) {
6380 color = getPixelColor(device, 480, 120);
6381 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6382 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
6384 if(shader_20_2) {
6385 color = getPixelColor(device, 160, 120);
6386 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6387 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
6389 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6390 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6392 IDirect3DVertexDeclaration9_Release(decl);
6393 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
6394 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
6395 IDirect3DVertexShader9_Release(shader_11_2);
6396 IDirect3DVertexShader9_Release(shader_11);
6397 refcount = IDirect3DDevice9_Release(device);
6398 ok(!refcount, "Device has %u references left.\n", refcount);
6399 done:
6400 IDirect3D9_Release(d3d);
6401 DestroyWindow(window);
6404 static void constant_clamp_ps_test(void)
6406 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
6407 IDirect3DDevice9 *device;
6408 IDirect3D9 *d3d;
6409 ULONG refcount;
6410 D3DCAPS9 caps;
6411 DWORD color;
6412 HWND window;
6413 HRESULT hr;
6415 static const DWORD shader_code_11[] =
6417 0xffff0101, /* ps_1_1 */
6418 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6419 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6420 0x0000ffff /* end */
6422 static const DWORD shader_code_12[] =
6424 0xffff0102, /* ps_1_2 */
6425 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6426 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6427 0x0000ffff /* end */
6429 /* Skip 1.3 shaders because we have only 4 quads (ok, could make them
6430 * smaller if needed). 1.2 and 1.4 shaders behave the same, so it's
6431 * unlikely that 1.3 shaders are different. During development of this
6432 * test, 1.3 shaders were verified too. */
6433 static const DWORD shader_code_14[] =
6435 0xffff0104, /* ps_1_4 */
6436 /* Try to make one constant local. It gets clamped too, although the
6437 * binary contains the bigger numbers. */
6438 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
6439 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6440 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6441 0x0000ffff /* end */
6443 static const DWORD shader_code_20[] =
6445 0xffff0200, /* ps_2_0 */
6446 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6447 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6448 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6449 0x0000ffff /* end */
6451 static const float quad1[] =
6453 -1.0f, -1.0f, 0.1f,
6454 -1.0f, 0.0f, 0.1f,
6455 0.0f, -1.0f, 0.1f,
6456 0.0f, 0.0f, 0.1f,
6458 static const float quad2[] =
6460 0.0f, -1.0f, 0.1f,
6461 0.0f, 0.0f, 0.1f,
6462 1.0f, -1.0f, 0.1f,
6463 1.0f, 0.0f, 0.1f,
6465 static const float quad3[] =
6467 0.0f, 0.0f, 0.1f,
6468 0.0f, 1.0f, 0.1f,
6469 1.0f, 0.0f, 0.1f,
6470 1.0f, 1.0f, 0.1f,
6472 static const float quad4[] =
6474 -1.0f, 0.0f, 0.1f,
6475 -1.0f, 1.0f, 0.1f,
6476 0.0f, 0.0f, 0.1f,
6477 0.0f, 1.0f, 0.1f,
6479 static const float test_data_c1[4] = { 1.25f, -0.50f, -1.50f, 1.0f};
6480 static const float test_data_c2[4] = {-0.50f, 1.25f, 2.00f, 1.0f};
6482 window = create_window();
6483 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6484 ok(!!d3d, "Failed to create a D3D object.\n");
6485 if (!(device = create_device(d3d, window, window, TRUE)))
6487 skip("Failed to create a D3D device, skipping tests.\n");
6488 goto done;
6491 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6492 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6493 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
6495 skip("No ps_1_4 support, skipping tests.\n");
6496 IDirect3DDevice9_Release(device);
6497 goto done;
6500 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
6501 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6503 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
6504 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6505 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
6506 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6507 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
6508 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6509 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
6510 if(FAILED(hr)) shader_20 = NULL;
6512 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
6513 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6514 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
6515 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6516 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6517 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6519 hr = IDirect3DDevice9_BeginScene(device);
6520 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6522 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
6523 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6524 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
6525 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6527 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
6528 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6529 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
6530 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6532 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
6533 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6534 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
6535 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6537 if (shader_20)
6539 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
6540 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6541 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
6542 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6545 hr = IDirect3DDevice9_EndScene(device);
6546 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6548 color = getPixelColor(device, 160, 360);
6549 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
6550 "quad 1 has color %08x, expected 0x00808000\n", color);
6551 color = getPixelColor(device, 480, 360);
6552 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
6553 "quad 2 has color %08x, expected 0x00808000\n", color);
6554 color = getPixelColor(device, 480, 120);
6555 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
6556 "quad 3 has color %08x, expected 0x00808000\n", color);
6557 if(shader_20) {
6558 color = getPixelColor(device, 160, 120);
6559 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6560 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
6562 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6563 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6565 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
6566 IDirect3DPixelShader9_Release(shader_14);
6567 IDirect3DPixelShader9_Release(shader_12);
6568 IDirect3DPixelShader9_Release(shader_11);
6569 refcount = IDirect3DDevice9_Release(device);
6570 ok(!refcount, "Device has %u references left.\n", refcount);
6571 done:
6572 IDirect3D9_Release(d3d);
6573 DestroyWindow(window);
6576 static void dp2add_ps_test(void)
6578 IDirect3DPixelShader9 *shader_dp2add_sat;
6579 IDirect3DPixelShader9 *shader_dp2add;
6580 IDirect3DDevice9 *device;
6581 IDirect3D9 *d3d;
6582 ULONG refcount;
6583 D3DCAPS9 caps;
6584 DWORD color;
6585 HWND window;
6586 HRESULT hr;
6588 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
6589 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
6590 * source tokens can be constants. So, for this exercise, we move contents of c0 to
6591 * r0 first.
6592 * The result here for the r,g,b components should be roughly 0.5:
6593 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
6594 static const DWORD shader_code_dp2add[] = {
6595 0xffff0200, /* ps_2_0 */
6596 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
6598 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6599 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
6601 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
6602 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6603 0x0000ffff /* end */
6606 /* Test the _sat modifier, too. Result here should be:
6607 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
6608 * _SAT: ==> 1.0
6609 * ADD: (1.0 + -0.5) = 0.5
6611 static const DWORD shader_code_dp2add_sat[] = {
6612 0xffff0200, /* ps_2_0 */
6613 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
6615 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6616 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
6617 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
6619 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
6620 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6621 0x0000ffff /* end */
6623 static const float quad[] =
6625 -1.0f, -1.0f, 0.1f,
6626 -1.0f, 1.0f, 0.1f,
6627 1.0f, -1.0f, 0.1f,
6628 1.0f, 1.0f, 0.1f,
6631 window = create_window();
6632 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6633 ok(!!d3d, "Failed to create a D3D object.\n");
6634 if (!(device = create_device(d3d, window, window, TRUE)))
6636 skip("Failed to create a D3D device, skipping tests.\n");
6637 goto done;
6640 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6641 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6642 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
6644 skip("No ps_2_0 support, skipping tests.\n");
6645 IDirect3DDevice9_Release(device);
6646 goto done;
6649 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
6650 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6652 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
6653 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6655 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
6656 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6658 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6659 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6661 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
6662 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
6663 hr = IDirect3DDevice9_BeginScene(device);
6664 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6665 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
6666 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
6667 hr = IDirect3DDevice9_EndScene(device);
6668 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6670 color = getPixelColor(device, 360, 240);
6671 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1), "Got unexpected color 0x%08x.\n", color);
6673 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6674 ok(SUCCEEDED(hr), "Failed to present frame, hr %#x.\n", hr);
6675 IDirect3DPixelShader9_Release(shader_dp2add);
6677 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
6678 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
6679 hr = IDirect3DDevice9_BeginScene(device);
6680 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6681 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
6682 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
6683 hr = IDirect3DDevice9_EndScene(device);
6684 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6686 color = getPixelColor(device, 360, 240);
6687 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1), "Got unexpected color 0x%08x.\n", color);
6689 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6690 ok(SUCCEEDED(hr), "Failed to present frame, hr %#x.\n", hr);
6691 IDirect3DPixelShader9_Release(shader_dp2add_sat);
6693 refcount = IDirect3DDevice9_Release(device);
6694 ok(!refcount, "Device has %u references left.\n", refcount);
6695 done:
6696 IDirect3D9_Release(d3d);
6697 DestroyWindow(window);
6700 static void cnd_test(void)
6702 IDirect3DPixelShader9 *shader_11_coissue_2, *shader_12_coissue_2, *shader_13_coissue_2, *shader_14_coissue_2;
6703 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
6704 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
6705 IDirect3DDevice9 *device;
6706 IDirect3D9 *d3d;
6707 ULONG refcount;
6708 D3DCAPS9 caps;
6709 HWND window;
6710 DWORD color;
6711 HRESULT hr;
6713 /* ps 1.x shaders are rather picky with writemasks and source swizzles.
6714 * The dp3 is used to copy r0.r to all components of r1, then copy r1.a to
6715 * r0.a. Essentially it does a mov r0.a, r0.r, which isn't allowed as-is
6716 * in 1.x pixel shaders. */
6717 static const DWORD shader_code_11[] =
6719 0xffff0101, /* ps_1_1 */
6720 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6721 0x00000040, 0xb00f0000, /* texcoord t0 */
6722 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
6723 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
6724 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6725 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
6726 0x0000ffff /* end */
6728 static const DWORD shader_code_12[] =
6730 0xffff0102, /* ps_1_2 */
6731 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6732 0x00000040, 0xb00f0000, /* texcoord t0 */
6733 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6734 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
6735 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6736 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
6737 0x0000ffff /* end */
6739 static const DWORD shader_code_13[] =
6741 0xffff0103, /* ps_1_3 */
6742 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6743 0x00000040, 0xb00f0000, /* texcoord t0 */
6744 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6745 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
6746 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6747 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
6748 0x0000ffff /* end */
6750 static const DWORD shader_code_14[] =
6752 0xffff0104, /* ps_1_3 */
6753 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6754 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
6755 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
6756 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
6757 0x0000ffff /* end */
6760 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
6761 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
6762 * set by the compiler, it was added manually after compilation. Note that the COISSUE
6763 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
6764 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
6765 * well enough.
6767 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
6768 * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
6769 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
6770 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
6772 static const DWORD shader_code_11_coissue[] =
6774 0xffff0101, /* ps_1_1 */
6775 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6776 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6777 0x00000040, 0xb00f0000, /* texcoord t0 */
6778 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6779 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6780 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6781 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6782 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6783 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6784 0x0000ffff /* end */
6786 static const DWORD shader_code_11_coissue_2[] =
6788 0xffff0101, /* ps_1_1 */
6789 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6790 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6791 0x00000040, 0xb00f0000, /* texcoord t0 */
6792 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6793 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6794 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6795 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6796 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6797 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6798 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6799 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6800 0x0000ffff /* end */
6802 static const DWORD shader_code_12_coissue[] =
6804 0xffff0102, /* ps_1_2 */
6805 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6806 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6807 0x00000040, 0xb00f0000, /* texcoord t0 */
6808 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6809 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6810 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6811 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6812 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6813 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6814 0x0000ffff /* end */
6816 static const DWORD shader_code_12_coissue_2[] =
6818 0xffff0102, /* ps_1_2 */
6819 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6820 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6821 0x00000040, 0xb00f0000, /* texcoord t0 */
6822 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6823 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6824 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6825 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6826 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6827 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6828 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6829 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6830 0x0000ffff /* end */
6832 static const DWORD shader_code_13_coissue[] =
6834 0xffff0103, /* ps_1_3 */
6835 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6836 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6837 0x00000040, 0xb00f0000, /* texcoord t0 */
6838 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6839 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6840 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6841 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6842 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6843 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6844 0x0000ffff /* end */
6846 static const DWORD shader_code_13_coissue_2[] =
6848 0xffff0103, /* ps_1_3 */
6849 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6850 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6851 0x00000040, 0xb00f0000, /* texcoord t0 */
6852 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6853 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6854 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6855 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6856 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6857 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6858 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6859 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6860 0x0000ffff /* end */
6862 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1]
6863 * texcrd result to cnd, it will compare against 0.5. */
6864 static const DWORD shader_code_14_coissue[] =
6866 0xffff0104, /* ps_1_4 */
6867 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6868 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
6869 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
6870 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0, c1, c2 */
6871 0x0000ffff /* end */
6873 static const DWORD shader_code_14_coissue_2[] =
6875 0xffff0104, /* ps_1_4 */
6876 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6877 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
6878 0x00000001, 0x80080000, 0x80000000, /* mov r0.a, r0.x */
6879 0x00000001, 0x80070001, 0xa0ff0000, /* mov r1.xyz, c0.a */
6880 0x40000050, 0x80080001, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r1.a, r0.a, c1, c2 */
6881 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6882 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
6883 0x0000ffff /* end */
6885 static const float quad1[] =
6887 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6888 -1.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6889 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6890 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6892 static const float quad2[] =
6894 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6895 0.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6896 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6897 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6899 static const float quad3[] =
6901 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6902 0.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6903 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6904 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6906 static const float quad4[] =
6908 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6909 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6910 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6911 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6913 static const float test_data_c1[4] = {0.0f, 0.0f, 0.0f, 0.0f};
6914 static const float test_data_c2[4] = {1.0f, 1.0f, 1.0f, 1.0f};
6915 static const float test_data_c1_coi[4] = {0.0f, 1.0f, 0.0f, 0.0f};
6916 static const float test_data_c2_coi[4] = {1.0f, 0.0f, 1.0f, 1.0f};
6918 window = create_window();
6919 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6920 ok(!!d3d, "Failed to create a D3D object.\n");
6921 if (!(device = create_device(d3d, window, window, TRUE)))
6923 skip("Failed to create a D3D device, skipping tests.\n");
6924 goto done;
6927 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6928 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6929 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
6931 skip("No ps_1_4 support, skipping tests.\n");
6932 IDirect3DDevice9_Release(device);
6933 goto done;
6936 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
6937 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6939 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
6940 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6941 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
6942 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6943 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
6944 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6945 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
6946 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6947 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
6948 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6949 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
6950 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6951 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
6952 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6953 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
6954 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6955 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue_2, &shader_11_coissue_2);
6956 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6957 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue_2, &shader_12_coissue_2);
6958 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6959 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue_2, &shader_13_coissue_2);
6960 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6961 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue_2, &shader_14_coissue_2);
6962 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6964 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
6965 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6966 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
6967 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6968 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6969 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6971 hr = IDirect3DDevice9_BeginScene(device);
6972 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6974 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
6975 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6976 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6977 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6979 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
6980 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6981 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
6982 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6984 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
6985 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6986 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
6987 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6989 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
6990 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6991 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
6992 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6994 hr = IDirect3DDevice9_EndScene(device);
6995 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6997 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6998 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
7000 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
7001 color = getPixelColor(device, 158, 118);
7002 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
7003 color = getPixelColor(device, 162, 118);
7004 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
7005 color = getPixelColor(device, 158, 122);
7006 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
7007 color = getPixelColor(device, 162, 122);
7008 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
7010 /* 1.1 shader. All 3 components get set, based on the .w comparison */
7011 color = getPixelColor(device, 158, 358);
7012 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
7013 color = getPixelColor(device, 162, 358);
7014 ok(color_match(color, 0x00000000, 1), "pixel 162, 358 has color 0x%08x, expected 0x00000000.\n", color);
7015 color = getPixelColor(device, 158, 362);
7016 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
7017 color = getPixelColor(device, 162, 362);
7018 ok(color_match(color, 0x00000000, 1), "pixel 162, 362 has color 0x%08x, expected 0x00000000.\n", color);
7020 /* 1.2 shader */
7021 color = getPixelColor(device, 478, 358);
7022 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
7023 color = getPixelColor(device, 482, 358);
7024 ok(color_match(color, 0x00000000, 1), "pixel 482, 358 has color 0x%08x, expected 0x00000000.\n", color);
7025 color = getPixelColor(device, 478, 362);
7026 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
7027 color = getPixelColor(device, 482, 362);
7028 ok(color_match(color, 0x00000000, 1), "pixel 482, 362 has color 0x%08x, expected 0x00000000.\n", color);
7030 /* 1.3 shader */
7031 color = getPixelColor(device, 478, 118);
7032 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
7033 color = getPixelColor(device, 482, 118);
7034 ok(color_match(color, 0x00000000, 1), "pixel 482, 118 has color 0x%08x, expected 0x00000000.\n", color);
7035 color = getPixelColor(device, 478, 122);
7036 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
7037 color = getPixelColor(device, 482, 122);
7038 ok(color_match(color, 0x00000000, 1), "pixel 482, 122 has color 0x%08x, expected 0x00000000.\n", color);
7040 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7041 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7043 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
7044 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7045 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
7046 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
7047 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
7048 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
7050 hr = IDirect3DDevice9_BeginScene(device);
7051 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7053 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
7054 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
7055 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
7056 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7058 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
7059 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
7060 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
7061 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7063 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
7064 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
7065 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
7066 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7068 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
7069 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
7070 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
7071 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7073 hr = IDirect3DDevice9_EndScene(device);
7074 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7076 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7077 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7079 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
7080 * that we swapped the values in c1 and c2 to make the other tests return some color
7082 color = getPixelColor(device, 158, 118);
7083 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
7084 color = getPixelColor(device, 162, 118);
7085 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
7086 color = getPixelColor(device, 158, 122);
7087 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
7088 color = getPixelColor(device, 162, 122);
7089 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
7091 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
7092 * (The Win7 nvidia driver always selects c2)
7094 color = getPixelColor(device, 158, 358);
7095 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7096 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
7097 color = getPixelColor(device, 162, 358);
7098 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7099 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
7100 color = getPixelColor(device, 158, 362);
7101 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7102 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
7103 color = getPixelColor(device, 162, 362);
7104 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7105 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
7107 /* 1.2 shader */
7108 color = getPixelColor(device, 478, 358);
7109 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7110 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
7111 color = getPixelColor(device, 482, 358);
7112 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7113 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
7114 color = getPixelColor(device, 478, 362);
7115 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7116 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
7117 color = getPixelColor(device, 482, 362);
7118 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7119 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
7121 /* 1.3 shader */
7122 color = getPixelColor(device, 478, 118);
7123 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7124 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
7125 color = getPixelColor(device, 482, 118);
7126 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7127 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
7128 color = getPixelColor(device, 478, 122);
7129 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7130 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
7131 color = getPixelColor(device, 482, 122);
7132 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7133 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
7135 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7136 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7138 /* Retest with the coissue flag on the alpha instruction instead. This
7139 * works "as expected". The Windows 8 testbot (WARP) seems to handle this
7140 * the same as coissue on .rgb. */
7141 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
7142 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7144 hr = IDirect3DDevice9_BeginScene(device);
7145 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7147 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue_2);
7148 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
7149 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
7150 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7152 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue_2);
7153 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
7154 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
7155 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7157 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue_2);
7158 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
7159 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
7160 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7162 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue_2);
7163 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
7164 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
7165 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7167 hr = IDirect3DDevice9_EndScene(device);
7168 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7170 /* 1.4 shader */
7171 color = getPixelColor(device, 158, 118);
7172 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
7173 color = getPixelColor(device, 162, 118);
7174 ok(color == 0x00000000, "pixel 162, 118 has color %08x, expected 0x00000000\n", color);
7175 color = getPixelColor(device, 158, 122);
7176 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
7177 color = getPixelColor(device, 162, 122);
7178 ok(color == 0x00000000, "pixel 162, 122 has color %08x, expected 0x00000000\n", color);
7180 /* 1.1 shader */
7181 color = getPixelColor(device, 238, 358);
7182 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
7183 "pixel 238, 358 has color %08x, expected 0x00ffffff\n", color);
7184 color = getPixelColor(device, 242, 358);
7185 ok(color_match(color, 0x00000000, 1),
7186 "pixel 242, 358 has color %08x, expected 0x00000000\n", color);
7187 color = getPixelColor(device, 238, 362);
7188 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
7189 "pixel 238, 362 has color %08x, expected 0x00ffffff\n", color);
7190 color = getPixelColor(device, 242, 362);
7191 ok(color_match(color, 0x00000000, 1),
7192 "pixel 242, 362 has color %08x, expected 0x00000000\n", color);
7194 /* 1.2 shader */
7195 color = getPixelColor(device, 558, 358);
7196 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
7197 "pixel 558, 358 has color %08x, expected 0x00ffffff\n", color);
7198 color = getPixelColor(device, 562, 358);
7199 ok(color_match(color, 0x00000000, 1),
7200 "pixel 562, 358 has color %08x, expected 0x00000000\n", color);
7201 color = getPixelColor(device, 558, 362);
7202 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
7203 "pixel 558, 362 has color %08x, expected 0x00ffffff\n", color);
7204 color = getPixelColor(device, 562, 362);
7205 ok(color_match(color, 0x00000000, 1),
7206 "pixel 562, 362 has color %08x, expected 0x00000000\n", color);
7208 /* 1.3 shader */
7209 color = getPixelColor(device, 558, 118);
7210 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
7211 "pixel 558, 118 has color %08x, expected 0x00ffffff\n", color);
7212 color = getPixelColor(device, 562, 118);
7213 ok(color_match(color, 0x00000000, 1),
7214 "pixel 562, 118 has color %08x, expected 0x00000000\n", color);
7215 color = getPixelColor(device, 558, 122);
7216 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
7217 "pixel 558, 122 has color %08x, expected 0x00ffffff\n", color);
7218 color = getPixelColor(device, 562, 122);
7219 ok(color_match(color, 0x00000000, 1),
7220 "pixel 562, 122 has color %08x, expected 0x00000000\n", color);
7222 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7223 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7225 IDirect3DPixelShader9_Release(shader_14_coissue_2);
7226 IDirect3DPixelShader9_Release(shader_13_coissue_2);
7227 IDirect3DPixelShader9_Release(shader_12_coissue_2);
7228 IDirect3DPixelShader9_Release(shader_11_coissue_2);
7229 IDirect3DPixelShader9_Release(shader_14_coissue);
7230 IDirect3DPixelShader9_Release(shader_13_coissue);
7231 IDirect3DPixelShader9_Release(shader_12_coissue);
7232 IDirect3DPixelShader9_Release(shader_11_coissue);
7233 IDirect3DPixelShader9_Release(shader_14);
7234 IDirect3DPixelShader9_Release(shader_13);
7235 IDirect3DPixelShader9_Release(shader_12);
7236 IDirect3DPixelShader9_Release(shader_11);
7237 refcount = IDirect3DDevice9_Release(device);
7238 ok(!refcount, "Device has %u references left.\n", refcount);
7239 done:
7240 IDirect3D9_Release(d3d);
7241 DestroyWindow(window);
7244 static void nested_loop_test(void)
7246 IDirect3DVertexShader9 *vshader;
7247 IDirect3DPixelShader9 *shader;
7248 IDirect3DDevice9 *device;
7249 IDirect3D9 *d3d;
7250 ULONG refcount;
7251 D3DCAPS9 caps;
7252 DWORD color;
7253 HWND window;
7254 HRESULT hr;
7256 static const DWORD shader_code[] =
7258 0xffff0300, /* ps_3_0 */
7259 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
7260 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
7261 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
7262 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7263 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
7264 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
7265 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
7266 0x0000001d, /* endloop */
7267 0x0000001d, /* endloop */
7268 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7269 0x0000ffff /* end */
7271 static const DWORD vshader_code[] =
7273 0xfffe0300, /* vs_3_0 */
7274 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7275 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7276 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7277 0x0000ffff /* end */
7279 static const float quad[] =
7281 -1.0f, -1.0f, 0.1f,
7282 -1.0f, 1.0f, 0.1f,
7283 1.0f, -1.0f, 0.1f,
7284 1.0f, 1.0f, 0.1f,
7287 window = create_window();
7288 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7289 ok(!!d3d, "Failed to create a D3D object.\n");
7290 if (!(device = create_device(d3d, window, window, TRUE)))
7292 skip("Failed to create a D3D device, skipping tests.\n");
7293 goto done;
7296 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7297 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7298 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
7300 skip("No shader model 3 support, skipping tests.\n");
7301 IDirect3DDevice9_Release(device);
7302 goto done;
7305 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7306 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
7307 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7308 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
7309 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
7310 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
7311 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
7312 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
7313 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7314 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
7315 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 1.0f, 0);
7316 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7318 hr = IDirect3DDevice9_BeginScene(device);
7319 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7320 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
7321 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7322 hr = IDirect3DDevice9_EndScene(device);
7323 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7325 color = getPixelColor(device, 360, 240);
7326 ok(color_match(color, 0x00800000, 1),
7327 "Nested loop test returned color 0x%08x, expected 0x00800000.\n", color);
7329 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7330 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7332 IDirect3DPixelShader9_Release(shader);
7333 IDirect3DVertexShader9_Release(vshader);
7334 refcount = IDirect3DDevice9_Release(device);
7335 ok(!refcount, "Device has %u references left.\n", refcount);
7336 done:
7337 IDirect3D9_Release(d3d);
7338 DestroyWindow(window);
7341 static void pretransformed_varying_test(void)
7343 /* dcl_position: fails to compile */
7344 static const DWORD blendweight_code[] =
7346 0xffff0300, /* ps_3_0 */
7347 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
7348 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7349 0x0000ffff /* end */
7351 static const DWORD blendindices_code[] =
7353 0xffff0300, /* ps_3_0 */
7354 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
7355 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7356 0x0000ffff /* end */
7358 static const DWORD normal_code[] =
7360 0xffff0300, /* ps_3_0 */
7361 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
7362 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7363 0x0000ffff /* end */
7365 /* psize: fails? */
7366 static const DWORD texcoord0_code[] =
7368 0xffff0300, /* ps_3_0 */
7369 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
7370 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7371 0x0000ffff /* end */
7373 static const DWORD tangent_code[] =
7375 0xffff0300, /* ps_3_0 */
7376 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
7377 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7378 0x0000ffff /* end */
7380 static const DWORD binormal_code[] =
7382 0xffff0300, /* ps_3_0 */
7383 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
7384 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7385 0x0000ffff /* end */
7387 /* tessfactor: fails */
7388 /* positiont: fails */
7389 static const DWORD color_code[] =
7391 0xffff0300, /* ps_3_0 */
7392 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
7393 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7394 0x0000ffff /* end */
7396 static const DWORD fog_code[] =
7398 0xffff0300, /* ps_3_0 */
7399 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
7400 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7401 0x0000ffff /* end */
7403 static const DWORD depth_code[] =
7405 0xffff0300, /* ps_3_0 */
7406 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
7407 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7408 0x0000ffff /* end */
7410 static const DWORD specular_code[] =
7412 0xffff0300, /* ps_3_0 */
7413 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
7414 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7415 0x0000ffff /* end */
7417 /* sample: fails */
7418 static const DWORD texcoord1_code[] =
7420 0xffff0300, /* ps_3_0 */
7421 0x0200001f, 0x80010005, 0x900f0000, /* dcl_texcoord1, v0 */
7422 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7423 0x0000ffff /* end */
7425 static const DWORD texcoord1_alpha_code[] =
7427 0xffff0300, /* ps_3_0 */
7428 0x0200001f, 0x80010005, 0x900f0000, /* dcl_texcoord1, v0 */
7429 0x02000001, 0x800f0800, 0x90ff0000, /* mov oC0, v0.w */
7430 0x0000ffff /* end */
7433 static const struct
7435 const char *name;
7436 const DWORD *shader_code;
7437 DWORD color;
7438 BOOL todo;
7439 BOOL broken;
7440 DWORD broken_color;
7442 tests[] =
7444 {"blendweight", blendweight_code, 0x00191919, TRUE },
7445 {"blendindices", blendindices_code, 0x00333333, TRUE },
7446 {"normal", normal_code, 0x004c4c4c, TRUE },
7447 {"texcoord0", texcoord0_code, 0x00808c8c, FALSE},
7448 {"tangent", tangent_code, 0x00999999, TRUE },
7449 {"binormal", binormal_code, 0x00b2b2b2, TRUE },
7450 {"color", color_code, 0x00e6e6e6, FALSE},
7451 {"fog", fog_code, 0x00666666, TRUE },
7452 {"depth", depth_code, 0x00cccccc, TRUE },
7453 {"specular", specular_code, 0x004488ff, FALSE},
7454 {"texcoord1", texcoord1_code, 0x00000000, FALSE},
7455 /* texcoord .w is 1.0 on r500 and WARP. See also test_uninitialized_varyings(). */
7456 {"texcoord1 alpha", texcoord1_alpha_code, 0x00000000, FALSE, TRUE, 0x00ffffff},
7458 /* Declare a monster vertex type :-) */
7459 static const D3DVERTEXELEMENT9 decl_elements[] = {
7460 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
7461 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
7462 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
7463 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
7464 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
7465 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7466 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
7467 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
7468 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
7469 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7470 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
7471 D3DDECL_END()
7474 static const struct
7476 float pos_x, pos_y, pos_z, rhw;
7477 float weight_1, weight_2, weight_3, weight_4;
7478 float index_1, index_2, index_3, index_4;
7479 float normal_1, normal_2, normal_3, normal_4;
7480 float fog_1, fog_2, fog_3, fog_4;
7481 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
7482 float tangent_1, tangent_2, tangent_3, tangent_4;
7483 float binormal_1, binormal_2, binormal_3, binormal_4;
7484 float depth_1, depth_2, depth_3, depth_4;
7485 D3DCOLOR diffuse;
7486 D3DCOLOR specular;
7488 data[] =
7491 0.0f, 0.0f, 0.1f, 1.0f,
7492 0.1f, 0.1f, 0.1f, 0.1f,
7493 0.2f, 0.2f, 0.2f, 0.2f,
7494 0.3f, 0.3f, 0.3f, 0.3f,
7495 0.4f, 0.4f, 0.4f, 0.4f,
7496 0.5f, 0.55f, 0.55f, 0.55f,
7497 0.6f, 0.6f, 0.6f, 0.7f,
7498 0.7f, 0.7f, 0.7f, 0.6f,
7499 0.8f, 0.8f, 0.8f, 0.8f,
7500 0xe6e6e6e6, /* 0.9 * 256 */
7501 0x224488ff, /* Nothing special */
7504 640.0f, 0.0f, 0.1f, 1.0f,
7505 0.1f, 0.1f, 0.1f, 0.1f,
7506 0.2f, 0.2f, 0.2f, 0.2f,
7507 0.3f, 0.3f, 0.3f, 0.3f,
7508 0.4f, 0.4f, 0.4f, 0.4f,
7509 0.5f, 0.55f, 0.55f, 0.55f,
7510 0.6f, 0.6f, 0.6f, 0.7f,
7511 0.7f, 0.7f, 0.7f, 0.6f,
7512 0.8f, 0.8f, 0.8f, 0.8f,
7513 0xe6e6e6e6, /* 0.9 * 256 */
7514 0x224488ff, /* Nothing special */
7517 0.0f, 480.0f, 0.1f, 1.0f,
7518 0.1f, 0.1f, 0.1f, 0.1f,
7519 0.2f, 0.2f, 0.2f, 0.2f,
7520 0.3f, 0.3f, 0.3f, 0.3f,
7521 0.4f, 0.4f, 0.4f, 0.4f,
7522 0.5f, 0.55f, 0.55f, 0.55f,
7523 0.6f, 0.6f, 0.6f, 0.7f,
7524 0.7f, 0.7f, 0.7f, 0.6f,
7525 0.8f, 0.8f, 0.8f, 0.8f,
7526 0xe6e6e6e6, /* 0.9 * 256 */
7527 0x224488ff, /* Nothing special */
7530 640.0f, 480.0f, 0.1f, 1.0f,
7531 0.1f, 0.1f, 0.1f, 0.1f,
7532 0.2f, 0.2f, 0.2f, 0.2f,
7533 0.3f, 0.3f, 0.3f, 0.3f,
7534 0.4f, 0.4f, 0.4f, 0.4f,
7535 0.5f, 0.55f, 0.55f, 0.55f,
7536 0.6f, 0.6f, 0.6f, 0.7f,
7537 0.7f, 0.7f, 0.7f, 0.6f,
7538 0.8f, 0.8f, 0.8f, 0.8f,
7539 0xe6e6e6e6, /* 0.9 * 256 */
7540 0x224488ff, /* Nothing special */
7543 IDirect3DVertexDeclaration9 *decl;
7544 IDirect3DDevice9 *device;
7545 IDirect3D9 *d3d;
7546 unsigned int i;
7547 ULONG refcount;
7548 D3DCAPS9 caps;
7549 DWORD color;
7550 HWND window;
7551 HRESULT hr;
7553 window = create_window();
7554 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7555 ok(!!d3d, "Failed to create a D3D object.\n");
7556 if (!(device = create_device(d3d, window, window, TRUE)))
7558 skip("Failed to create a D3D device, skipping tests.\n");
7559 goto done;
7562 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7563 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7564 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
7566 skip("No shader model 3 support, skipping tests.\n");
7567 IDirect3DDevice9_Release(device);
7568 goto done;
7571 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
7572 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7573 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
7574 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
7576 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
7578 IDirect3DPixelShader9 *shader;
7580 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
7581 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7583 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &shader);
7584 ok(SUCCEEDED(hr), "Failed to create pixel shader for test %s, hr %#x.\n", tests[i].name, hr);
7586 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7587 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7589 hr = IDirect3DDevice9_BeginScene(device);
7590 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7591 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(*data));
7592 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7593 hr = IDirect3DDevice9_EndScene(device);
7594 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7596 /* This isn't a weekend's job to fix, ignore the problem for now.
7597 * Needs a replacement pipeline. */
7598 color = getPixelColor(device, 360, 240);
7599 if (tests[i].todo)
7600 todo_wine ok(color_match(color, tests[i].color, 1)
7601 || broken(color_match(color, 0x00000000, 1)
7602 && tests[i].shader_code == blendindices_code),
7603 "Test %s returned color 0x%08x, expected 0x%08x (todo).\n",
7604 tests[i].name, color, tests[i].color);
7605 else
7606 ok(color_match(color, tests[i].color, 1)
7607 || broken(color_match(color, tests[i].broken_color, 1) && tests[i].broken),
7608 "Test %s returned color 0x%08x, expected 0x%08x.\n",
7609 tests[i].name, color, tests[i].color);
7611 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7612 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7614 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7615 ok(SUCCEEDED(hr), "Failed to set pixel shader for test %s, hr %#x.\n", tests[i].name, hr);
7616 IDirect3DPixelShader9_Release(shader);
7619 IDirect3DVertexDeclaration9_Release(decl);
7620 refcount = IDirect3DDevice9_Release(device);
7621 ok(!refcount, "Device has %u references left.\n", refcount);
7622 done:
7623 IDirect3D9_Release(d3d);
7624 DestroyWindow(window);
7627 static void test_compare_instructions(void)
7629 IDirect3DVertexShader9 *shader_slt_scalar;
7630 IDirect3DVertexShader9 *shader_sge_scalar;
7631 IDirect3DVertexShader9 *shader_slt_vec;
7632 IDirect3DVertexShader9 *shader_sge_vec;
7633 IDirect3DDevice9 *device;
7634 IDirect3D9 *d3d;
7635 D3DCOLOR color;
7636 ULONG refcount;
7637 D3DCAPS9 caps;
7638 HWND window;
7639 HRESULT hr;
7641 static const DWORD shader_sge_vec_code[] =
7643 0xfffe0101, /* vs_1_1 */
7644 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7645 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7646 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7647 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
7648 0x0000ffff /* end */
7650 static const DWORD shader_slt_vec_code[] =
7652 0xfffe0101, /* vs_1_1 */
7653 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7654 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7655 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7656 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
7657 0x0000ffff /* end */
7659 static const DWORD shader_sge_scalar_code[] =
7661 0xfffe0101, /* vs_1_1 */
7662 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7663 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7664 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7665 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
7666 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
7667 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
7668 0x0000ffff /* end */
7670 static const DWORD shader_slt_scalar_code[] =
7672 0xfffe0101, /* vs_1_1 */
7673 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7674 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7675 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7676 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
7677 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
7678 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
7679 0x0000ffff /* end */
7681 static const float quad1[] =
7683 -1.0f, -1.0f, 0.1f,
7684 -1.0f, 0.0f, 0.1f,
7685 0.0f, -1.0f, 0.1f,
7686 0.0f, 0.0f, 0.1f,
7688 static const float quad2[] =
7690 0.0f, -1.0f, 0.1f,
7691 0.0f, 0.0f, 0.1f,
7692 1.0f, -1.0f, 0.1f,
7693 1.0f, 0.0f, 0.1f,
7695 static const float quad3[] =
7697 -1.0f, 0.0f, 0.1f,
7698 -1.0f, 1.0f, 0.1f,
7699 0.0f, 0.0f, 0.1f,
7700 0.0f, 1.0f, 0.1f,
7702 static const float quad4[] =
7704 0.0f, 0.0f, 0.1f,
7705 0.0f, 1.0f, 0.1f,
7706 1.0f, 0.0f, 0.1f,
7707 1.0f, 1.0f, 0.1f,
7709 static const float const0[4] = {0.8f, 0.2f, 0.2f, 0.2f};
7710 static const float const1[4] = {0.2f, 0.8f, 0.2f, 0.2f};
7712 window = create_window();
7713 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7714 ok(!!d3d, "Failed to create a D3D object.\n");
7715 if (!(device = create_device(d3d, window, window, TRUE)))
7717 skip("Failed to create a D3D device, skipping tests.\n");
7718 goto done;
7721 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7722 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7723 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
7725 skip("No vs_1_1 support, skipping tests.\n");
7726 IDirect3DDevice9_Release(device);
7727 goto done;
7730 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
7731 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
7733 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
7734 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7735 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
7736 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7737 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
7738 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7739 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
7740 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7741 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
7742 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
7743 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
7744 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
7745 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7746 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
7748 hr = IDirect3DDevice9_BeginScene(device);
7749 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7751 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
7752 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7753 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
7754 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7756 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
7757 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7758 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
7759 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7761 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
7762 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7763 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
7764 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7766 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
7767 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
7769 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
7770 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7771 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
7772 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7774 hr = IDirect3DDevice9_EndScene(device);
7775 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7777 color = getPixelColor(device, 160, 360);
7778 ok(color == 0x00ff00ff, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00ff00ff\n", color);
7779 color = getPixelColor(device, 480, 360);
7780 ok(color == 0x0000ff00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000ff00\n", color);
7781 color = getPixelColor(device, 160, 120);
7782 ok(color == 0x00ffffff, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00ffffff\n", color);
7783 color = getPixelColor(device, 480, 160);
7784 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
7786 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7787 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7789 IDirect3DVertexShader9_Release(shader_sge_vec);
7790 IDirect3DVertexShader9_Release(shader_slt_vec);
7791 IDirect3DVertexShader9_Release(shader_sge_scalar);
7792 IDirect3DVertexShader9_Release(shader_slt_scalar);
7793 refcount = IDirect3DDevice9_Release(device);
7794 ok(!refcount, "Device has %u references left.\n", refcount);
7795 done:
7796 IDirect3D9_Release(d3d);
7797 DestroyWindow(window);
7800 static void test_vshader_input(void)
7802 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
7803 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
7804 IDirect3DVertexDeclaration9 *decl_nocolor;
7805 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
7806 D3DADAPTER_IDENTIFIER9 identifier;
7807 IDirect3DPixelShader9 *ps;
7808 IDirect3DDevice9 *device;
7809 IDirect3D9 *d3d;
7810 ULONG refcount;
7811 unsigned int i;
7812 D3DCAPS9 caps;
7813 DWORD color;
7814 HWND window;
7815 HRESULT hr;
7816 BOOL warp;
7818 static const DWORD swapped_shader_code_3[] =
7820 0xfffe0300, /* vs_3_0 */
7821 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7822 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7823 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7824 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7825 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7826 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7827 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7828 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7829 0x0000ffff /* end */
7831 static const DWORD swapped_shader_code_1[] =
7833 0xfffe0101, /* vs_1_1 */
7834 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7835 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7836 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7837 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
7838 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7839 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7840 0x0000ffff /* end */
7842 static const DWORD swapped_shader_code_2[] =
7844 0xfffe0200, /* vs_2_0 */
7845 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7846 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7847 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7848 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
7849 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7850 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7851 0x0000ffff /* end */
7853 static const DWORD texcoord_color_shader_code_3[] =
7855 0xfffe0300, /* vs_3_0 */
7856 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7857 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7858 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7859 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7860 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7861 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
7862 0x0000ffff /* end */
7864 static const DWORD texcoord_color_shader_code_2[] =
7866 0xfffe0200, /* vs_2_0 */
7867 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7868 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7869 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7870 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
7871 0x0000ffff /* end */
7873 static const DWORD texcoord_color_shader_code_1[] =
7875 0xfffe0101, /* vs_1_1 */
7876 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7877 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7878 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7879 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
7880 0x0000ffff /* end */
7882 static const DWORD color_color_shader_code_3[] =
7884 0xfffe0300, /* vs_3_0 */
7885 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7886 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7887 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7888 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7889 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7890 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
7891 0x0000ffff /* end */
7893 static const DWORD color_color_shader_code_2[] =
7895 0xfffe0200, /* vs_2_0 */
7896 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7897 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7898 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7899 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
7900 0x0000ffff /* end */
7902 static const DWORD color_color_shader_code_1[] =
7904 0xfffe0101, /* vs_1_1 */
7905 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7906 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7907 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7908 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
7909 0x0000ffff /* end */
7911 static const DWORD ps3_code[] =
7913 0xffff0300, /* ps_3_0 */
7914 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
7915 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7916 0x0000ffff /* end */
7918 static const float quad1[] =
7920 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7921 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7922 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7923 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7925 static const float quad2[] =
7927 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7928 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7929 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7930 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7932 static const float quad3[] =
7934 -1.0f, 0.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f,
7935 -1.0f, 1.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
7936 0.0f, 0.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
7937 0.0f, 1.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
7939 static const float quad4[] =
7941 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7942 0.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7943 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7944 1.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7946 static const float quad1_modified[] =
7948 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
7949 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f,
7950 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
7951 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, -1.0f, -1.0f, 0.0f,
7953 static const float quad2_modified[] =
7955 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7956 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7957 1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7958 1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7960 static const struct
7962 struct vec3 position;
7963 DWORD diffuse;
7965 quad1_color[] =
7967 {{-1.0f, -1.0f, 0.1f}, 0x00ff8040},
7968 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
7969 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7970 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7972 quad2_color[] =
7974 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7975 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7976 {{ 1.0f, -1.0f, 0.1f}, 0x00ff8040},
7977 {{ 1.0f, 0.0f, 0.1f}, 0x00ff8040},
7979 quad3_color[] =
7981 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
7982 {{-1.0f, 1.0f, 0.1f}, 0x00ff8040},
7983 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7984 {{ 0.0f, 1.0f, 0.1f}, 0x00ff8040},
7986 static const float quad4_color[] =
7988 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7989 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7990 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7991 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7993 static const struct vec3 quad_nocolor[] =
7995 {-1.0f, -1.0f, 0.1f},
7996 {-1.0f, 1.0f, 0.1f},
7997 { 1.0f, -1.0f, 0.1f},
7998 { 1.0f, 1.0f, 0.1f},
8000 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] =
8002 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8003 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8004 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
8005 D3DDECL_END()
8007 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] =
8009 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8010 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
8011 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8012 D3DDECL_END()
8014 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] =
8016 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8017 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8018 D3DDECL_END()
8020 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] =
8022 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8023 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
8024 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
8025 D3DDECL_END()
8027 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] =
8029 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8030 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8031 D3DDECL_END()
8033 static const D3DVERTEXELEMENT9 decl_elements_color_color[] =
8035 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8036 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8037 D3DDECL_END()
8039 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] =
8041 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8042 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8043 D3DDECL_END()
8045 static const D3DVERTEXELEMENT9 decl_elements_color_float[] =
8047 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8048 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8049 D3DDECL_END()
8051 static const D3DVERTEXELEMENT9 decl_elements_nocolor[] =
8053 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8054 D3DDECL_END()
8056 static const float normalize[4] = {1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f};
8057 static const float no_normalize[4] = {1.0f, 1.0f, 1.0f, 1.0f};
8059 window = create_window();
8060 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8061 ok(!!d3d, "Failed to create a D3D object.\n");
8062 if (!(device = create_device(d3d, window, window, TRUE)))
8064 skip("Failed to create a D3D device, skipping tests.\n");
8065 goto done;
8068 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8069 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
8070 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
8072 skip("No vs_3_0 support, skipping tests.\n");
8073 IDirect3DDevice9_Release(device);
8074 goto done;
8076 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
8078 skip("No ps_3_0 support, skipping tests.\n");
8079 IDirect3DDevice9_Release(device);
8080 goto done;
8083 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
8084 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
8085 warp = adapter_is_warp(&identifier);
8087 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
8088 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
8089 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
8090 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
8091 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
8092 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
8093 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
8094 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
8096 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
8097 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
8098 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
8099 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
8100 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
8101 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
8102 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
8103 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
8104 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_nocolor, &decl_nocolor);
8105 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
8107 hr = IDirect3DDevice9_CreatePixelShader(device, ps3_code, &ps);
8108 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
8110 for (i = 1; i <= 3; ++i)
8112 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
8113 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
8114 if(i == 3) {
8115 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
8116 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8117 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8118 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
8119 } else if(i == 2){
8120 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
8121 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8122 } else if(i == 1) {
8123 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
8124 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8127 hr = IDirect3DDevice9_BeginScene(device);
8128 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8130 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
8131 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8133 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
8134 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8135 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
8136 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8138 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
8139 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8140 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
8141 if (i == 3 || i == 2)
8142 ok(SUCCEEDED(hr), "Failed to draw, i %u, hr %#x.\n", i, hr);
8143 else if (i == 1)
8144 /* Succeeds or fails, depending on SW or HW vertex processing. */
8145 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
8147 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
8148 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8149 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
8150 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8152 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
8153 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8154 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
8155 if (i == 3 || i == 2)
8156 ok(SUCCEEDED(hr), "Failed to draw, i %u, hr %#x.\n", i, hr);
8157 else if (i == 1)
8158 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
8160 hr = IDirect3DDevice9_EndScene(device);
8161 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8163 if(i == 3 || i == 2) {
8164 color = getPixelColor(device, 160, 360);
8165 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
8166 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00ffff80\n", color);
8168 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
8169 color = getPixelColor(device, 480, 360);
8170 /* On the Windows 8 testbot (WARP) the draw succeeds, but uses
8171 * mostly random data as input. */
8172 ok(color == 0x00ffff00 || color == 0x00ff0000 || broken(warp),
8173 "Got unexpected color 0x%08x for quad 2 (1crd).\n", color);
8174 color = getPixelColor(device, 160, 120);
8175 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
8176 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
8177 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00ff0080\n", color);
8179 color = getPixelColor(device, 480, 160);
8180 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
8181 } else if(i == 1) {
8182 color = getPixelColor(device, 160, 360);
8183 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
8184 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00ffff80\n", color);
8185 color = getPixelColor(device, 480, 360);
8186 /* Accept the clear color as well in this case, since SW VP
8187 * returns an error. On the Windows 8 testbot (WARP) the draw
8188 * succeeds, but uses mostly random data as input. */
8189 ok(color == 0x00ffff00 || color == 0x00ff0000 || broken(warp),
8190 "Got unexpected color 0x%08x for quad 2 (1crd).\n", color);
8191 color = getPixelColor(device, 160, 120);
8192 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
8193 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00ff0080\n", color);
8194 color = getPixelColor(device, 480, 160);
8195 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
8198 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8199 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8201 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
8202 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8204 /* Now find out if the whole streams are re-read, or just the last
8205 * active value for the vertices is used. */
8206 hr = IDirect3DDevice9_BeginScene(device);
8207 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8209 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
8210 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8212 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
8213 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8214 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
8215 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8217 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
8218 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8219 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
8220 if (i == 3 || i == 2)
8221 ok(SUCCEEDED(hr), "Failed to draw, i %u, hr %#x.\n", i, hr);
8222 else if (i == 1)
8223 /* Succeeds or fails, depending on SW or HW vertex processing. */
8224 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
8226 hr = IDirect3DDevice9_EndScene(device);
8227 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8229 color = getPixelColor(device, 480, 350);
8230 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
8231 * as well.
8233 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
8234 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
8235 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
8236 * refrast's result.
8238 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
8240 ok(color == 0x000000ff || color == 0x00808080 || color == 0x00000000
8241 || broken(color_match(color, D3DCOLOR_ARGB(0x00, 0x0b, 0x75, 0x80), 1)),
8242 "Got unexpected color 0x%08x for quad 2 (different colors).\n", color);
8244 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8245 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8247 IDirect3DDevice9_SetVertexShader(device, NULL);
8248 IDirect3DDevice9_SetPixelShader(device, NULL);
8249 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8251 IDirect3DVertexShader9_Release(swapped_shader);
8254 for (i = 1; i <= 3; ++i)
8256 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
8257 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
8258 if(i == 3) {
8259 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
8260 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8261 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
8262 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8263 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8264 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
8265 } else if(i == 2){
8266 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
8267 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8268 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
8269 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8270 } else if(i == 1) {
8271 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
8272 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8273 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
8274 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8277 hr = IDirect3DDevice9_BeginScene(device);
8278 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8280 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
8281 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8282 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
8283 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8284 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
8285 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8287 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
8288 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8290 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
8291 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
8292 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
8293 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8294 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
8295 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8297 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
8298 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
8299 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
8300 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8301 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
8302 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8304 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
8305 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8306 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
8307 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8309 hr = IDirect3DDevice9_EndScene(device);
8310 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8312 color = getPixelColor(device, 160, 360);
8313 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
8314 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
8315 color = getPixelColor(device, 480, 360);
8316 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
8317 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
8318 color = getPixelColor(device, 160, 120);
8319 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
8320 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
8321 color = getPixelColor(device, 480, 160);
8322 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
8323 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00ffff00\n", color);
8325 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8326 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8328 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_nocolor);
8329 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8331 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
8332 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8334 hr = IDirect3DDevice9_BeginScene(device);
8335 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8336 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_nocolor, sizeof(quad_nocolor[0]));
8337 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8338 hr = IDirect3DDevice9_EndScene(device);
8339 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8341 /* WARP and r500 return a color from a previous draw. In case of WARP it is random, although most of the
8342 * time it is the color of the last draw, which happens to be the one with quad4_color above. AMD's r500
8343 * uses the last D3DCOLOR attribute, which is the one from quad3_color.
8345 * Newer AMD cards and Nvidia return zero. */
8346 color = getPixelColor(device, 160, 360);
8347 ok(color_match(color, 0x00000000, 1) || broken(color_match(color, 0x00ff8040, 1)) || broken(warp),
8348 "Got unexpected color 0x%08x for no color attribute test.\n", color);
8350 IDirect3DDevice9_SetVertexShader(device, NULL);
8351 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8352 IDirect3DDevice9_SetPixelShader(device, NULL);
8354 IDirect3DVertexShader9_Release(texcoord_color_shader);
8355 IDirect3DVertexShader9_Release(color_color_shader);
8358 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
8359 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
8360 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
8361 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
8363 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
8364 IDirect3DVertexDeclaration9_Release(decl_color_color);
8365 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
8366 IDirect3DVertexDeclaration9_Release(decl_color_float);
8367 IDirect3DVertexDeclaration9_Release(decl_nocolor);
8369 IDirect3DPixelShader9_Release(ps);
8370 refcount = IDirect3DDevice9_Release(device);
8371 ok(!refcount, "Device has %u references left.\n", refcount);
8372 done:
8373 IDirect3D9_Release(d3d);
8374 DestroyWindow(window);
8377 static void srgbtexture_test(void)
8379 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
8380 * texture stage state to render a quad using that texture. The resulting
8381 * color components should be 0x36 (~ 0.21), per this formula:
8382 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
8383 * This is true where srgb_color > 0.04045. */
8384 struct IDirect3DTexture9 *texture;
8385 struct IDirect3DSurface9 *surface;
8386 IDirect3DDevice9 *device;
8387 IDirect3D9 *d3d;
8388 D3DCOLOR color;
8389 ULONG refcount;
8390 HWND window;
8391 HRESULT hr;
8393 static const float quad[] =
8395 -1.0f, -1.0f, 0.0f, 0.0f, 1.0f,
8396 -1.0f, 1.0f, 0.0f, 0.0f, 0.0f,
8397 1.0f, -1.0f, 0.0f, 1.0f, 1.0f,
8398 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
8401 window = create_window();
8402 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8403 ok(!!d3d, "Failed to create a D3D object.\n");
8404 if (!(device = create_device(d3d, window, window, TRUE)))
8406 skip("Failed to create a D3D device, skipping tests.\n");
8407 goto done;
8410 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
8411 D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK)
8413 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported.\n");
8414 IDirect3DDevice9_Release(device);
8415 goto done;
8418 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
8419 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
8420 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8421 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
8423 fill_surface(surface, 0xff7f7f7f, 0);
8424 IDirect3DSurface9_Release(surface);
8426 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8427 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8428 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8429 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
8431 hr = IDirect3DDevice9_BeginScene(device);
8432 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8434 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
8435 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
8436 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8437 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8438 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
8439 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8441 hr = IDirect3DDevice9_EndScene(device);
8442 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8444 color = getPixelColor(device, 320, 240);
8445 ok(color_match(color, 0x00363636, 1), "sRGB quad has color 0x%08x, expected 0x00363636.\n", color);
8447 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8448 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8450 IDirect3DTexture9_Release(texture);
8451 refcount = IDirect3DDevice9_Release(device);
8452 ok(!refcount, "Device has %u references left.\n", refcount);
8453 done:
8454 IDirect3D9_Release(d3d);
8455 DestroyWindow(window);
8458 static void test_shademode(void)
8460 IDirect3DVertexBuffer9 *vb_strip;
8461 IDirect3DVertexBuffer9 *vb_list;
8462 IDirect3DVertexShader9 *vs;
8463 IDirect3DPixelShader9 *ps;
8464 IDirect3DDevice9 *device;
8465 DWORD color0, color1;
8466 void *data = NULL;
8467 IDirect3D9 *d3d;
8468 ULONG refcount;
8469 D3DCAPS9 caps;
8470 HWND window;
8471 HRESULT hr;
8472 UINT i;
8473 static const DWORD vs1_code[] =
8475 0xfffe0101, /* vs_1_1 */
8476 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8477 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
8478 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8479 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
8480 0x0000ffff
8482 static const DWORD vs2_code[] =
8484 0xfffe0200, /* vs_2_0 */
8485 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8486 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
8487 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8488 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
8489 0x0000ffff
8491 static const DWORD vs3_code[] =
8493 0xfffe0300, /* vs_3_0 */
8494 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8495 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
8496 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8497 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
8498 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8499 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
8500 0x0000ffff
8502 static const DWORD ps1_code[] =
8504 0xffff0101, /* ps_1_1 */
8505 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
8506 0x0000ffff
8508 static const DWORD ps2_code[] =
8510 0xffff0200, /* ps_2_0 */
8511 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
8512 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8513 0x0000ffff
8515 static const DWORD ps3_code[] =
8517 0xffff0300, /* ps_3_0 */
8518 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
8519 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8520 0x0000ffff
8522 static const struct
8524 struct vec3 position;
8525 DWORD diffuse;
8527 quad_strip[] =
8529 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
8530 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8531 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8532 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
8534 quad_list[] =
8536 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
8537 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8538 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8540 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8541 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8542 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
8544 static const struct test_shader
8546 DWORD version;
8547 const DWORD *code;
8549 novs = {0, NULL},
8550 vs_1 = {D3DVS_VERSION(1, 1), vs1_code},
8551 vs_2 = {D3DVS_VERSION(2, 0), vs2_code},
8552 vs_3 = {D3DVS_VERSION(3, 0), vs3_code},
8553 nops = {0, NULL},
8554 ps_1 = {D3DPS_VERSION(1, 1), ps1_code},
8555 ps_2 = {D3DPS_VERSION(2, 0), ps2_code},
8556 ps_3 = {D3DPS_VERSION(3, 0), ps3_code};
8557 static const struct
8559 const struct test_shader *vs, *ps;
8560 DWORD primtype;
8561 DWORD shademode;
8562 DWORD color0, color1;
8563 BOOL todo;
8565 tests[] =
8567 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8568 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_PHONG, 0x000dca28, 0x000d45c7, FALSE},
8569 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8570 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_PHONG, 0x000dca28, 0x000d45c7, FALSE},
8571 {&novs, &nops, D3DPT_TRIANGLELIST, D3DSHADE_FLAT, 0x00ff0000, 0x000000ff, FALSE},
8572 {&novs, &nops, D3DPT_TRIANGLELIST, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8573 {&vs_1, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8574 {&vs_1, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8575 {&vs_1, &ps_1, D3DPT_TRIANGLELIST, D3DSHADE_FLAT, 0x00ff0000, 0x000000ff, FALSE},
8576 {&vs_1, &ps_1, D3DPT_TRIANGLELIST, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8577 {&novs, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8578 {&vs_1, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8579 {&vs_2, &ps_2, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8580 {&vs_2, &ps_2, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8581 {&vs_3, &ps_3, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, TRUE},
8582 {&vs_3, &ps_3, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8585 window = create_window();
8586 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8587 ok(!!d3d, "Failed to create a D3D object.\n");
8588 if (!(device = create_device(d3d, window, window, TRUE)))
8590 skip("Failed to create a D3D device, skipping tests.\n");
8591 goto done;
8594 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8595 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8596 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
8597 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
8599 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8600 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
8602 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip), 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
8603 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8604 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
8605 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8606 memcpy(data, quad_strip, sizeof(quad_strip));
8607 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
8608 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
8610 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list), 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
8611 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8612 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
8613 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8614 memcpy(data, quad_list, sizeof(quad_list));
8615 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
8616 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
8618 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8619 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
8621 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
8622 * the color fixups we have to do for FLAT shading will be dependent on that. */
8624 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
8626 if (tests[i].vs->version)
8628 if (caps.VertexShaderVersion >= tests[i].vs->version)
8630 hr = IDirect3DDevice9_CreateVertexShader(device, tests[i].vs->code, &vs);
8631 ok(hr == D3D_OK, "Failed to create vertex shader, hr %#x.\n", hr);
8632 hr = IDirect3DDevice9_SetVertexShader(device, vs);
8633 ok(hr == D3D_OK, "Failed to set vertex shader, hr %#x.\n", hr);
8635 else
8637 skip("Shader version unsupported, skipping some tests.\n");
8638 continue;
8641 else
8643 vs = NULL;
8645 if (tests[i].ps->version)
8647 if (caps.PixelShaderVersion >= tests[i].ps->version)
8649 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].ps->code, &ps);
8650 ok(hr == D3D_OK, "Failed to create pixel shader, hr %#x.\n", hr);
8651 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8652 ok(hr == D3D_OK, "Failed to set pixel shader, hr %#x.\n", hr);
8654 else
8656 skip("Shader version unsupported, skipping some tests.\n");
8657 if (vs)
8659 IDirect3DDevice9_SetVertexShader(device, NULL);
8660 IDirect3DVertexShader9_Release(vs);
8662 continue;
8665 else
8667 ps = NULL;
8670 hr = IDirect3DDevice9_SetStreamSource(device, 0,
8671 tests[i].primtype == D3DPT_TRIANGLESTRIP ? vb_strip : vb_list, 0, sizeof(quad_strip[0]));
8672 ok(hr == D3D_OK, "Failed to set stream source, hr %#x.\n", hr);
8674 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
8675 ok(hr == D3D_OK, "Failed to clear, hr %#x.\n", hr);
8677 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shademode);
8678 ok(hr == D3D_OK, "Failed to set shade mode, hr %#x.\n", hr);
8680 hr = IDirect3DDevice9_BeginScene(device);
8681 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8682 hr = IDirect3DDevice9_DrawPrimitive(device, tests[i].primtype, 0, 2);
8683 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8684 hr = IDirect3DDevice9_EndScene(device);
8685 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8687 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
8688 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
8690 /* For D3DSHADE_FLAT it should take the color of the first vertex of
8691 * each triangle. This requires EXT_provoking_vertex or similar
8692 * functionality being available. */
8693 /* PHONG should be the same as GOURAUD, since no hardware implements
8694 * this. */
8695 todo_wine_if (tests[i].todo)
8697 ok(color_match(color0, tests[i].color0, 1), "Test %u shading has color0 %08x, expected %08x.\n",
8698 i, color0, tests[i].color0);
8699 ok(color_match(color1, tests[i].color1, 1), "Test %u shading has color1 %08x, expected %08x.\n",
8700 i, color1, tests[i].color1);
8702 IDirect3DDevice9_SetVertexShader(device, NULL);
8703 IDirect3DDevice9_SetPixelShader(device, NULL);
8705 if (ps)
8706 IDirect3DPixelShader9_Release(ps);
8707 if (vs)
8708 IDirect3DVertexShader9_Release(vs);
8711 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8712 ok(hr == D3D_OK, "Failed to present, hr %#x.\n", hr);
8714 IDirect3DVertexBuffer9_Release(vb_strip);
8715 IDirect3DVertexBuffer9_Release(vb_list);
8716 refcount = IDirect3DDevice9_Release(device);
8717 ok(!refcount, "Device has %u references left.\n", refcount);
8718 done:
8719 IDirect3D9_Release(d3d);
8720 DestroyWindow(window);
8723 static void test_blend(void)
8725 IDirect3DSurface9 *backbuffer, *offscreen;
8726 IDirect3DTexture9 *offscreenTexture;
8727 IDirect3DDevice9 *device;
8728 IDirect3D9 *d3d;
8729 D3DCOLOR color;
8730 ULONG refcount;
8731 HWND window;
8732 HRESULT hr;
8734 static const struct
8736 struct vec3 position;
8737 DWORD diffuse;
8739 quad1[] =
8741 {{-1.0f, -1.0f, 0.1f}, 0x4000ff00},
8742 {{-1.0f, 0.0f, 0.1f}, 0x4000ff00},
8743 {{ 1.0f, -1.0f, 0.1f}, 0x4000ff00},
8744 {{ 1.0f, 0.0f, 0.1f}, 0x4000ff00},
8746 quad2[] =
8748 {{-1.0f, 0.0f, 0.1f}, 0xc00000ff},
8749 {{-1.0f, 1.0f, 0.1f}, 0xc00000ff},
8750 {{ 1.0f, 0.0f, 0.1f}, 0xc00000ff},
8751 {{ 1.0f, 1.0f, 0.1f}, 0xc00000ff},
8753 static const float composite_quad[][5] =
8755 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
8756 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
8757 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
8758 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
8761 window = create_window();
8762 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8763 ok(!!d3d, "Failed to create a D3D object.\n");
8764 if (!(device = create_device(d3d, window, window, TRUE)))
8766 skip("Failed to create a D3D device, skipping tests.\n");
8767 goto done;
8770 /* Clear the render target with alpha = 0.5 */
8771 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x80ff0000, 1.0f, 0);
8772 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8774 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
8775 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8776 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
8778 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8779 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8781 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8782 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8784 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8785 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
8787 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8788 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8789 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8790 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8791 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8792 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8793 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8794 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8795 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8796 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8798 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8799 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8800 hr = IDirect3DDevice9_BeginScene(device);
8801 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8803 /* Draw two quads, one with src alpha blending, one with dest alpha
8804 * blending. */
8805 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8806 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8807 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8808 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8809 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8810 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8812 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
8813 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8814 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
8815 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8816 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8817 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8819 /* Switch to the offscreen buffer, and redo the testing. The offscreen
8820 * render target doesn't have an alpha channel. DESTALPHA and INVDESTALPHA
8821 * "don't work" on render targets without alpha channel, they give
8822 * essentially ZERO and ONE blend factors. */
8823 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8824 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8825 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x80ff0000, 1.0f, 0);
8826 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8828 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8829 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8830 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8831 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8832 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8833 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8835 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
8836 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8837 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
8838 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8839 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8840 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8842 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8843 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8845 /* Render the offscreen texture onto the frame buffer to be able to
8846 * compare it regularly. Disable alpha blending for the final
8847 * composition. */
8848 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8849 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8850 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8851 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8853 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8854 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
8855 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
8856 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8858 hr = IDirect3DDevice9_EndScene(device);
8859 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8861 color = getPixelColor(device, 160, 360);
8862 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
8863 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
8865 color = getPixelColor(device, 160, 120);
8866 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
8867 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
8869 color = getPixelColor(device, 480, 360);
8870 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
8871 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
8873 color = getPixelColor(device, 480, 120);
8874 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
8875 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
8877 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8879 IDirect3DSurface9_Release(backbuffer);
8880 IDirect3DTexture9_Release(offscreenTexture);
8881 IDirect3DSurface9_Release(offscreen);
8882 refcount = IDirect3DDevice9_Release(device);
8883 ok(!refcount, "Device has %u references left.\n", refcount);
8884 done:
8885 IDirect3D9_Release(d3d);
8886 DestroyWindow(window);
8889 static void fixed_function_decl_test(void)
8891 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
8892 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_nocolor, *dcl_positiont;
8893 IDirect3DVertexBuffer9 *vb, *vb2;
8894 IDirect3DDevice9 *device;
8895 BOOL s_ok, ub_ok, f_ok;
8896 DWORD color, size, i;
8897 IDirect3D9 *d3d;
8898 ULONG refcount;
8899 D3DCAPS9 caps;
8900 HWND window;
8901 void *data;
8902 HRESULT hr;
8904 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
8905 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8906 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8907 D3DDECL_END()
8909 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
8910 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8911 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8912 D3DDECL_END()
8914 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
8915 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8916 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8917 D3DDECL_END()
8919 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
8920 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8921 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8922 D3DDECL_END()
8924 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
8925 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8926 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8927 D3DDECL_END()
8929 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
8930 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8931 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8932 D3DDECL_END()
8934 static const D3DVERTEXELEMENT9 decl_elements_nocolor[] = {
8935 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8936 D3DDECL_END()
8938 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
8939 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
8940 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8941 D3DDECL_END()
8943 static const struct
8945 struct vec3 position;
8946 DWORD diffuse;
8948 quad1[] = /* D3DCOLOR */
8950 {{-1.0f, -1.0f, 0.1f}, 0x00ffff00},
8951 {{-1.0f, 0.0f, 0.1f}, 0x00ffff00},
8952 {{ 0.0f, -1.0f, 0.1f}, 0x00ffff00},
8953 {{ 0.0f, 0.0f, 0.1f}, 0x00ffff00},
8955 quad2[] = /* UBYTE4N */
8957 {{-1.0f, 0.0f, 0.1f}, 0x00ffff00},
8958 {{-1.0f, 1.0f, 0.1f}, 0x00ffff00},
8959 {{ 0.0f, 0.0f, 0.1f}, 0x00ffff00},
8960 {{ 0.0f, 1.0f, 0.1f}, 0x00ffff00},
8962 static const struct
8964 struct vec3 position;
8965 struct { unsigned short x, y, z, w; } color;
8967 quad3[] = /* USHORT4N */
8969 {{0.0f, -1.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8970 {{0.0f, 0.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8971 {{1.0f, -1.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8972 {{1.0f, 0.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8974 static const struct
8976 struct vec3 position;
8977 struct vec4 color;
8979 quad4[] =
8981 {{0.0f, 0.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8982 {{0.0f, 1.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8983 {{1.0f, 0.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8984 {{1.0f, 1.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8986 static const DWORD colors[] =
8988 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8989 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8990 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8991 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8992 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8993 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8994 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8995 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8996 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8997 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8998 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8999 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9000 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9001 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9002 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9003 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9005 static const float quads[] =
9007 -1.0f, -1.0f, 0.1f,
9008 -1.0f, 0.0f, 0.1f,
9009 0.0f, -1.0f, 0.1f,
9010 0.0f, 0.0f, 0.1f,
9012 0.0f, -1.0f, 0.1f,
9013 0.0f, 0.0f, 0.1f,
9014 1.0f, -1.0f, 0.1f,
9015 1.0f, 0.0f, 0.1f,
9017 0.0f, 0.0f, 0.1f,
9018 0.0f, 1.0f, 0.1f,
9019 1.0f, 0.0f, 0.1f,
9020 1.0f, 1.0f, 0.1f,
9022 -1.0f, 0.0f, 0.1f,
9023 -1.0f, 1.0f, 0.1f,
9024 0.0f, 0.0f, 0.1f,
9025 0.0f, 1.0f, 0.1f,
9027 static const struct
9029 struct vec4 position;
9030 DWORD diffuse;
9032 quad_transformed[] =
9034 {{ 90.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
9035 {{570.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
9036 {{ 90.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
9037 {{570.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
9040 window = create_window();
9041 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9042 ok(!!d3d, "Failed to create a D3D object.\n");
9043 if (!(device = create_device(d3d, window, window, TRUE)))
9045 skip("Failed to create a D3D device, skipping tests.\n");
9046 goto done;
9049 memset(&caps, 0, sizeof(caps));
9050 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9051 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
9053 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
9054 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9056 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
9057 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
9058 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
9059 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
9060 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
9061 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
9062 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
9063 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
9064 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
9065 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
9066 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
9067 } else {
9068 trace("D3DDTCAPS_UBYTE4N not supported\n");
9069 dcl_ubyte_2 = NULL;
9070 dcl_ubyte = NULL;
9072 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
9073 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
9074 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_nocolor, &dcl_nocolor);
9075 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
9076 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
9077 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
9079 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
9080 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
9081 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9082 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9084 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9085 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
9087 hr = IDirect3DDevice9_BeginScene(device);
9088 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9090 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
9091 if (dcl_color)
9093 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
9094 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9095 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9096 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9099 /* Tests with non-standard fixed function types fail on the refrast. The
9100 * ATI driver partially accepts them, the NVIDIA driver accepts them all.
9101 * All those differences even though we're using software vertex
9102 * processing. Doh! */
9103 if (dcl_ubyte)
9105 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
9106 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9107 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9108 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9109 ub_ok = SUCCEEDED(hr);
9112 if (dcl_short)
9114 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
9115 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9116 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
9117 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9118 s_ok = SUCCEEDED(hr);
9121 if (dcl_float)
9123 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
9124 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9125 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
9126 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9127 f_ok = SUCCEEDED(hr);
9130 hr = IDirect3DDevice9_EndScene(device);
9131 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9133 if(dcl_short) {
9134 color = getPixelColor(device, 480, 360);
9135 ok(color == 0x000000ff || !s_ok,
9136 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
9138 if(dcl_ubyte) {
9139 color = getPixelColor(device, 160, 120);
9140 ok(color == 0x0000ffff || !ub_ok,
9141 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
9143 if(dcl_color) {
9144 color = getPixelColor(device, 160, 360);
9145 ok(color == 0x00ffff00,
9146 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
9148 if(dcl_float) {
9149 color = getPixelColor(device, 480, 120);
9150 ok(color == 0x00ff0000 || !f_ok,
9151 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
9153 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9155 /* The following test with vertex buffers doesn't serve to find out new
9156 * information from windows. It is a plain regression test because wined3d
9157 * uses different codepaths for attribute conversion with vertex buffers.
9158 * It makes sure that the vertex buffer one works, while the above tests
9159 * whether the immediate mode code works. */
9160 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
9161 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
9162 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9163 hr = IDirect3DDevice9_BeginScene(device);
9164 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9166 if (dcl_color)
9168 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
9169 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
9170 memcpy(data, quad1, sizeof(quad1));
9171 hr = IDirect3DVertexBuffer9_Unlock(vb);
9172 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
9173 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
9174 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9175 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
9176 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
9177 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9178 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9181 if (dcl_ubyte)
9183 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
9184 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
9185 memcpy(data, quad2, sizeof(quad2));
9186 hr = IDirect3DVertexBuffer9_Unlock(vb);
9187 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
9188 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
9189 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9190 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
9191 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
9192 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9193 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9194 ub_ok = SUCCEEDED(hr);
9197 if (dcl_short)
9199 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
9200 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
9201 memcpy(data, quad3, sizeof(quad3));
9202 hr = IDirect3DVertexBuffer9_Unlock(vb);
9203 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
9204 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
9205 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9206 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
9207 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
9208 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9209 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9210 s_ok = SUCCEEDED(hr);
9213 if (dcl_float)
9215 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
9216 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
9217 memcpy(data, quad4, sizeof(quad4));
9218 hr = IDirect3DVertexBuffer9_Unlock(vb);
9219 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
9220 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
9221 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9222 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
9223 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
9224 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9225 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9226 f_ok = SUCCEEDED(hr);
9229 hr = IDirect3DDevice9_EndScene(device);
9230 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9232 if(dcl_short) {
9233 color = getPixelColor(device, 480, 360);
9234 ok(color == 0x000000ff || !s_ok,
9235 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
9237 if(dcl_ubyte) {
9238 color = getPixelColor(device, 160, 120);
9239 ok(color == 0x0000ffff || !ub_ok,
9240 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
9242 if(dcl_color) {
9243 color = getPixelColor(device, 160, 360);
9244 ok(color == 0x00ffff00,
9245 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
9247 if(dcl_float) {
9248 color = getPixelColor(device, 480, 120);
9249 ok(color == 0x00ff0000 || !f_ok,
9250 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
9252 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9254 /* Test with no diffuse color attribute. */
9255 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9256 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9258 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_nocolor);
9259 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9260 hr = IDirect3DDevice9_BeginScene(device);
9261 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9262 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quads, sizeof(float) * 3);
9263 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9264 hr = IDirect3DDevice9_EndScene(device);
9265 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9267 color = getPixelColor(device, 160, 360);
9268 ok(color == 0x00ffffff, "Got unexpected color 0x%08x in the no color attribute test.\n", color);
9270 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9272 /* Test what happens with specular lighting enabled and no specular color attribute. */
9273 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
9274 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
9275 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9276 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
9277 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#x.\n", hr);
9278 hr = IDirect3DDevice9_BeginScene(device);
9279 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9281 if (dcl_color)
9283 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
9284 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9285 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9286 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9288 if (dcl_ubyte)
9290 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
9291 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9292 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9293 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9294 ub_ok = SUCCEEDED(hr);
9296 if (dcl_short)
9298 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
9299 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9300 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
9301 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9302 s_ok = SUCCEEDED(hr);
9304 if (dcl_float)
9306 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
9307 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9308 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
9309 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9310 f_ok = SUCCEEDED(hr);
9313 hr = IDirect3DDevice9_EndScene(device);
9314 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9315 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARENABLE, FALSE);
9316 ok(SUCCEEDED(hr), "Failed to disable specular lighting, hr %#x.\n", hr);
9318 if (dcl_short)
9320 color = getPixelColor(device, 480, 360);
9321 ok(color == 0x000000ff || !s_ok,
9322 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff.\n", color);
9324 if (dcl_ubyte)
9326 color = getPixelColor(device, 160, 120);
9327 ok(color == 0x0000ffff || !ub_ok,
9328 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff.\n", color);
9330 if (dcl_color)
9332 color = getPixelColor(device, 160, 360);
9333 ok(color == 0x00ffff00,
9334 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00.\n", color);
9336 if (dcl_float)
9338 color = getPixelColor(device, 480, 120);
9339 ok(color == 0x00ff0000 || !f_ok,
9340 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000.\n", color);
9342 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9344 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
9345 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9346 memcpy(data, quad_transformed, sizeof(quad_transformed));
9347 hr = IDirect3DVertexBuffer9_Unlock(vb);
9348 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
9350 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
9351 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
9353 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9354 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9356 hr = IDirect3DDevice9_BeginScene(device);
9357 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9358 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
9359 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
9360 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9361 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9362 hr = IDirect3DDevice9_EndScene(device);
9363 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9365 color = getPixelColor(device, 88, 108);
9366 ok(color == 0x000000ff,
9367 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
9368 color = getPixelColor(device, 92, 108);
9369 ok(color == 0x000000ff,
9370 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
9371 color = getPixelColor(device, 88, 112);
9372 ok(color == 0x000000ff,
9373 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
9374 color = getPixelColor(device, 92, 112);
9375 ok(color == 0x00ffff00,
9376 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
9378 color = getPixelColor(device, 568, 108);
9379 ok(color == 0x000000ff,
9380 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
9381 color = getPixelColor(device, 572, 108);
9382 ok(color == 0x000000ff,
9383 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
9384 color = getPixelColor(device, 568, 112);
9385 ok(color == 0x00ffff00,
9386 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
9387 color = getPixelColor(device, 572, 112);
9388 ok(color == 0x000000ff,
9389 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
9391 color = getPixelColor(device, 88, 298);
9392 ok(color == 0x000000ff,
9393 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
9394 color = getPixelColor(device, 92, 298);
9395 ok(color == 0x00ffff00,
9396 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
9397 color = getPixelColor(device, 88, 302);
9398 ok(color == 0x000000ff,
9399 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
9400 color = getPixelColor(device, 92, 302);
9401 ok(color == 0x000000ff,
9402 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
9404 color = getPixelColor(device, 568, 298);
9405 ok(color == 0x00ffff00,
9406 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
9407 color = getPixelColor(device, 572, 298);
9408 ok(color == 0x000000ff,
9409 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
9410 color = getPixelColor(device, 568, 302);
9411 ok(color == 0x000000ff,
9412 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
9413 color = getPixelColor(device, 572, 302);
9414 ok(color == 0x000000ff,
9415 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
9417 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9419 /* This test is pointless without those two declarations: */
9420 if((!dcl_color_2) || (!dcl_ubyte_2)) {
9421 skip("color-ubyte switching test declarations aren't supported\n");
9422 goto out;
9425 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
9426 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9427 memcpy(data, quads, sizeof(quads));
9428 hr = IDirect3DVertexBuffer9_Unlock(vb);
9429 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
9430 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
9431 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9432 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9433 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
9434 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9435 memcpy(data, colors, sizeof(colors));
9436 hr = IDirect3DVertexBuffer9_Unlock(vb2);
9437 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
9439 for(i = 0; i < 2; i++) {
9440 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9441 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9443 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
9444 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
9445 if(i == 0) {
9446 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
9447 } else {
9448 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
9450 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
9452 hr = IDirect3DDevice9_BeginScene(device);
9453 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9455 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
9456 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9457 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9458 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9459 ub_ok = SUCCEEDED(hr);
9461 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
9462 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9463 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
9464 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9466 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
9467 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9468 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
9469 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9470 ub_ok = (SUCCEEDED(hr) && ub_ok);
9472 hr = IDirect3DDevice9_EndScene(device);
9473 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9475 if(i == 0) {
9476 color = getPixelColor(device, 480, 360);
9477 ok(color == 0x00ff0000,
9478 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
9479 color = getPixelColor(device, 160, 120);
9480 ok(color == 0x00ffffff,
9481 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
9482 color = getPixelColor(device, 160, 360);
9483 ok(color == 0x000000ff || !ub_ok,
9484 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
9485 color = getPixelColor(device, 480, 120);
9486 ok(color == 0x000000ff || !ub_ok,
9487 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
9488 } else {
9489 color = getPixelColor(device, 480, 360);
9490 ok(color == 0x000000ff,
9491 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
9492 color = getPixelColor(device, 160, 120);
9493 ok(color == 0x00ffffff,
9494 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
9495 color = getPixelColor(device, 160, 360);
9496 ok(color == 0x00ff0000 || !ub_ok,
9497 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
9498 color = getPixelColor(device, 480, 120);
9499 ok(color == 0x00ff0000 || !ub_ok,
9500 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
9502 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9505 IDirect3DVertexBuffer9_Release(vb2);
9506 out:
9507 IDirect3DVertexBuffer9_Release(vb);
9508 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
9509 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
9510 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
9511 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
9512 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
9513 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
9514 IDirect3DVertexDeclaration9_Release(dcl_nocolor);
9515 IDirect3DVertexDeclaration9_Release(dcl_positiont);
9516 refcount = IDirect3DDevice9_Release(device);
9517 ok(!refcount, "Device has %u references left.\n", refcount);
9518 done:
9519 IDirect3D9_Release(d3d);
9520 DestroyWindow(window);
9523 static void test_vshader_float16(void)
9525 IDirect3DVertexDeclaration9 *vdecl = NULL;
9526 IDirect3DVertexBuffer9 *buffer = NULL;
9527 IDirect3DVertexShader9 *shader;
9528 IDirect3DDevice9 *device;
9529 IDirect3D9 *d3d;
9530 ULONG refcount;
9531 D3DCAPS9 caps;
9532 DWORD color;
9533 HWND window;
9534 void *data;
9535 HRESULT hr;
9537 static const D3DVERTEXELEMENT9 decl_elements[] =
9539 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9540 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9541 D3DDECL_END()
9543 static const DWORD shader_code[] =
9545 0xfffe0101, /* vs_1_1 */
9546 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9547 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
9548 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
9549 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
9550 0x0000ffff,
9552 static const struct vertex_float16color
9554 float x, y, z;
9555 DWORD c1, c2;
9557 quad[] =
9559 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
9560 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
9561 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
9562 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
9564 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
9565 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
9566 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
9567 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
9569 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
9570 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
9571 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
9572 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
9574 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
9575 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
9576 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
9577 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
9580 window = create_window();
9581 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9582 ok(!!d3d, "Failed to create a D3D object.\n");
9583 if (!(device = create_device(d3d, window, window, TRUE)))
9585 skip("Failed to create a D3D device, skipping tests.\n");
9586 goto done;
9589 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9590 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
9591 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
9593 skip("No vs_3_0 support, skipping tests.\n");
9594 IDirect3DDevice9_Release(device);
9595 goto done;
9598 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff102030, 1.0f, 0);
9599 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9601 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
9602 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
9603 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9604 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9605 hr = IDirect3DDevice9_SetVertexShader(device, shader);
9606 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9608 hr = IDirect3DDevice9_BeginScene(device);
9609 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9610 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
9611 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9612 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
9613 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9614 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
9615 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9616 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
9617 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9618 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
9619 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9620 hr = IDirect3DDevice9_EndScene(device);
9621 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9623 color = getPixelColor(device, 480, 360);
9624 ok(color == 0x00ff0000,
9625 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
9626 color = getPixelColor(device, 160, 120);
9627 ok(color == 0x00000000,
9628 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
9629 color = getPixelColor(device, 160, 360);
9630 ok(color == 0x0000ff00,
9631 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
9632 color = getPixelColor(device, 480, 120);
9633 ok(color == 0x000000ff,
9634 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
9635 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9637 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
9638 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9640 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
9641 D3DPOOL_MANAGED, &buffer, NULL);
9642 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
9643 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
9644 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
9645 memcpy(data, quad, sizeof(quad));
9646 hr = IDirect3DVertexBuffer9_Unlock(buffer);
9647 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
9648 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
9649 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
9651 hr = IDirect3DDevice9_BeginScene(device);
9652 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9653 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9654 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9655 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
9656 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9657 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
9658 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9659 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
9660 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9661 hr = IDirect3DDevice9_EndScene(device);
9662 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9664 color = getPixelColor(device, 480, 360);
9665 ok(color == 0x00ff0000,
9666 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
9667 color = getPixelColor(device, 160, 120);
9668 ok(color == 0x00000000,
9669 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
9670 color = getPixelColor(device, 160, 360);
9671 ok(color == 0x0000ff00,
9672 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
9673 color = getPixelColor(device, 480, 120);
9674 ok(color == 0x000000ff,
9675 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
9676 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9678 IDirect3DVertexDeclaration9_Release(vdecl);
9679 IDirect3DVertexShader9_Release(shader);
9680 IDirect3DVertexBuffer9_Release(buffer);
9681 refcount = IDirect3DDevice9_Release(device);
9682 ok(!refcount, "Device has %u references left.\n", refcount);
9683 done:
9684 IDirect3D9_Release(d3d);
9685 DestroyWindow(window);
9688 static void conditional_np2_repeat_test(void)
9690 IDirect3DTexture9 *texture;
9691 IDirect3DDevice9 *device;
9692 D3DLOCKED_RECT rect;
9693 unsigned int x, y;
9694 DWORD *dst, color;
9695 IDirect3D9 *d3d;
9696 ULONG refcount;
9697 D3DCAPS9 caps;
9698 HWND window;
9699 HRESULT hr;
9701 static const float quad[] =
9703 -1.0f, -1.0f, 0.1f, -0.2f, -0.2f,
9704 -1.0f, 1.0f, 0.1f, -0.2f, 1.2f,
9705 1.0f, -1.0f, 0.1f, 1.2f, -0.2f,
9706 1.0f, 1.0f, 0.1f, 1.2f, 1.2f,
9709 window = create_window();
9710 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9711 ok(!!d3d, "Failed to create a D3D object.\n");
9712 if (!(device = create_device(d3d, window, window, TRUE)))
9714 skip("Failed to create a D3D device, skipping tests.\n");
9715 goto done;
9718 memset(&caps, 0, sizeof(caps));
9719 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9720 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
9721 if (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)
9723 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
9724 ok(caps.TextureCaps & D3DPTEXTURECAPS_POW2,
9725 "Card has conditional NP2 support without power of two restriction set\n");
9727 else if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
9729 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
9730 IDirect3DDevice9_Release(device);
9731 goto done;
9733 else
9735 skip("Card has unconditional NP2 support, skipping conditional NP2 tests\n");
9736 IDirect3DDevice9_Release(device);
9737 goto done;
9740 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
9741 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9743 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9744 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9746 memset(&rect, 0, sizeof(rect));
9747 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
9748 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9749 for(y = 0; y < 10; y++) {
9750 for(x = 0; x < 10; x++) {
9751 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
9752 if(x == 0 || x == 9 || y == 0 || y == 9) {
9753 *dst = 0x00ff0000;
9754 } else {
9755 *dst = 0x000000ff;
9759 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9760 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9762 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
9763 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9764 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9765 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
9766 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
9767 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
9768 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
9769 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
9770 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9771 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
9773 hr = IDirect3DDevice9_BeginScene(device);
9774 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9775 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9776 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9777 hr = IDirect3DDevice9_EndScene(device);
9778 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9780 color = getPixelColor(device, 1, 1);
9781 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
9782 color = getPixelColor(device, 639, 479);
9783 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
9785 color = getPixelColor(device, 135, 101);
9786 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
9787 color = getPixelColor(device, 140, 101);
9788 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
9789 color = getPixelColor(device, 135, 105);
9790 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
9791 color = getPixelColor(device, 140, 105);
9792 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
9794 color = getPixelColor(device, 135, 376);
9795 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
9796 color = getPixelColor(device, 140, 376);
9797 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
9798 color = getPixelColor(device, 135, 379);
9799 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
9800 color = getPixelColor(device, 140, 379);
9801 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
9803 color = getPixelColor(device, 500, 101);
9804 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
9805 color = getPixelColor(device, 504, 101);
9806 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
9807 color = getPixelColor(device, 500, 105);
9808 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
9809 color = getPixelColor(device, 504, 105);
9810 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
9812 color = getPixelColor(device, 500, 376);
9813 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
9814 color = getPixelColor(device, 504, 376);
9815 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
9816 color = getPixelColor(device, 500, 380);
9817 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
9818 color = getPixelColor(device, 504, 380);
9819 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
9821 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9823 IDirect3DTexture9_Release(texture);
9824 refcount = IDirect3DDevice9_Release(device);
9825 ok(!refcount, "Device has %u references left.\n", refcount);
9826 done:
9827 IDirect3D9_Release(d3d);
9828 DestroyWindow(window);
9831 static void vface_register_test(void)
9833 IDirect3DSurface9 *surface, *backbuffer;
9834 IDirect3DVertexShader9 *vshader;
9835 IDirect3DPixelShader9 *shader;
9836 IDirect3DTexture9 *texture;
9837 IDirect3DDevice9 *device;
9838 IDirect3D9 *d3d;
9839 ULONG refcount;
9840 D3DCAPS9 caps;
9841 DWORD color;
9842 HWND window;
9843 HRESULT hr;
9845 static const DWORD shader_code[] =
9847 0xffff0300, /* ps_3_0 */
9848 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9849 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
9850 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
9851 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
9852 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
9853 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
9854 0x0000ffff /* END */
9856 static const DWORD vshader_code[] =
9858 0xfffe0300, /* vs_3_0 */
9859 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9860 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
9861 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
9862 0x0000ffff /* end */
9864 static const float quad[] =
9866 -1.0f, -1.0f, 0.1f,
9867 1.0f, -1.0f, 0.1f,
9868 -1.0f, 0.0f, 0.1f,
9870 1.0f, -1.0f, 0.1f,
9871 1.0f, 0.0f, 0.1f,
9872 -1.0f, 0.0f, 0.1f,
9874 -1.0f, 0.0f, 0.1f,
9875 -1.0f, 1.0f, 0.1f,
9876 1.0f, 0.0f, 0.1f,
9878 1.0f, 0.0f, 0.1f,
9879 -1.0f, 1.0f, 0.1f,
9880 1.0f, 1.0f, 0.1f,
9882 static const float blit[] =
9884 0.0f, -1.0f, 0.1f, 0.0f, 0.0f,
9885 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
9886 0.0f, 1.0f, 0.1f, 0.0f, 1.0f,
9887 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
9890 window = create_window();
9891 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9892 ok(!!d3d, "Failed to create a D3D object.\n");
9893 if (!(device = create_device(d3d, window, window, TRUE)))
9895 skip("Failed to create a D3D device, skipping tests.\n");
9896 goto done;
9899 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9900 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
9901 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
9903 skip("No shader model 3 support, skipping tests.\n");
9904 IDirect3DDevice9_Release(device);
9905 goto done;
9908 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
9909 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9910 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
9911 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
9912 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
9913 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9914 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
9915 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
9916 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
9917 ok(SUCCEEDED(hr), "Failed to set cull mode, hr %#x.\n", hr);
9918 hr = IDirect3DDevice9_SetPixelShader(device, shader);
9919 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
9920 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
9921 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9922 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9923 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
9924 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9925 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
9927 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
9928 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9930 hr = IDirect3DDevice9_BeginScene(device);
9931 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9933 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
9934 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
9935 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
9936 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9937 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9938 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
9939 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9940 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9941 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
9942 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
9943 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9945 /* Blit the texture onto the back buffer to make it visible */
9946 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9947 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
9948 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9949 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9950 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
9951 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
9952 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9953 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
9954 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9955 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
9956 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9957 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9958 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
9959 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9961 hr = IDirect3DDevice9_EndScene(device);
9962 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9964 color = getPixelColor(device, 160, 360);
9965 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
9966 color = getPixelColor(device, 160, 120);
9967 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
9968 color = getPixelColor(device, 480, 360);
9969 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
9970 color = getPixelColor(device, 480, 120);
9971 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
9972 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9973 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
9975 IDirect3DPixelShader9_Release(shader);
9976 IDirect3DVertexShader9_Release(vshader);
9977 IDirect3DSurface9_Release(surface);
9978 IDirect3DSurface9_Release(backbuffer);
9979 IDirect3DTexture9_Release(texture);
9980 refcount = IDirect3DDevice9_Release(device);
9981 ok(!refcount, "Device has %u references left.\n", refcount);
9982 done:
9983 IDirect3D9_Release(d3d);
9984 DestroyWindow(window);
9987 static void fixed_function_bumpmap_test(void)
9989 IDirect3DVertexDeclaration9 *vertex_declaration;
9990 IDirect3DTexture9 *texture, *tex1, *tex2;
9991 D3DLOCKED_RECT locked_rect;
9992 IDirect3DDevice9 *device;
9993 BOOL L6V5U5_supported;
9994 float scale, offset;
9995 IDirect3D9 *d3d;
9996 unsigned int i;
9997 D3DCOLOR color;
9998 ULONG refcount;
9999 D3DCAPS9 caps;
10000 HWND window;
10001 HRESULT hr;
10003 static const float quad[][7] =
10005 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
10006 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
10007 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
10008 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
10010 static const D3DVERTEXELEMENT9 decl_elements[] =
10012 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
10013 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
10014 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
10015 D3DDECL_END()
10017 /* use asymmetric matrix to test loading */
10018 static const float bumpenvmat[4] = {0.0f, 0.5f, -0.5f, 0.0f};
10020 window = create_window();
10021 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10022 ok(!!d3d, "Failed to create a D3D object.\n");
10023 if (!(device = create_device(d3d, window, window, TRUE)))
10025 skip("Failed to create a D3D device, skipping tests.\n");
10026 goto done;
10029 memset(&caps, 0, sizeof(caps));
10030 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10031 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
10032 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP))
10034 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
10035 IDirect3DDevice9_Release(device);
10036 goto done;
10039 /* This check is disabled, some Windows drivers do not handle
10040 * D3DUSAGE_QUERY_LEGACYBUMPMAP properly. They report that it is not
10041 * supported, but after that bump mapping works properly. So just test if
10042 * the format is generally supported, and check the BUMPENVMAP flag. */
10043 L6V5U5_supported = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
10044 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_L6V5U5));
10045 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
10046 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_V8U8)))
10048 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
10049 IDirect3DDevice9_Release(device);
10050 return;
10053 /* Generate the textures */
10054 generate_bumpmap_textures(device);
10056 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
10057 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
10058 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
10059 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
10060 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
10061 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
10062 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
10063 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
10065 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
10066 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
10067 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
10068 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
10069 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
10070 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
10072 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10073 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
10074 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10075 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
10076 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
10077 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
10079 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
10080 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
10082 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10083 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
10085 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff00ff, 1.0f, 0);
10086 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
10088 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
10089 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
10090 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
10091 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
10093 hr = IDirect3DDevice9_BeginScene(device);
10094 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
10096 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
10097 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
10099 hr = IDirect3DDevice9_EndScene(device);
10100 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
10102 color = getPixelColor(device, 240, 60);
10103 ok(color_match(color, 0x005ea000, 4), "Got unexpected color 0x%08x.\n", color);
10104 color = getPixelColor(device, 400, 60);
10105 ok(color_match(color, 0x009ea000, 4), "Got unexpected color 0x%08x.\n", color);
10106 color = getPixelColor(device, 80, 180);
10107 ok(color_match(color, 0x005ea000, 4), "Got unexpected color 0x%08x.\n", color);
10108 color = getPixelColor(device, 560, 180);
10109 ok(color_match(color, 0x009ea000, 4), "Got unexpected color 0x%08x.\n", color);
10110 color = getPixelColor(device, 80, 300);
10111 ok(color_match(color, 0x005e6000, 4), "Got unexpected color 0x%08x.\n", color);
10112 color = getPixelColor(device, 560, 300);
10113 ok(color_match(color, 0x009e6000, 4), "Got unexpected color 0x%08x.\n", color);
10114 color = getPixelColor(device, 240, 420);
10115 ok(color_match(color, 0x005e6000, 4), "Got unexpected color 0x%08x.\n", color);
10116 color = getPixelColor(device, 400, 420);
10117 ok(color_match(color, 0x009e6000, 4), "Got unexpected color 0x%08x.\n", color);
10118 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10119 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10121 for(i = 0; i < 2; i++) {
10122 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
10123 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
10124 IDirect3DTexture9_Release(texture); /* For the GetTexture */
10125 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
10126 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
10127 IDirect3DTexture9_Release(texture); /* To destroy it */
10130 if (!L6V5U5_supported || !(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE))
10132 skip("L6V5U5 / D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping tests.\n");
10133 IDirect3DVertexDeclaration9_Release(vertex_declaration);
10134 IDirect3DDevice9_Release(device);
10135 goto done;
10138 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10139 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10140 /* This test only tests the luminance part. The bumpmapping part was already tested above and
10141 * would only make this test more complicated
10143 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
10144 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
10145 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
10146 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
10148 memset(&locked_rect, 0, sizeof(locked_rect));
10149 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
10150 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10151 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
10152 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
10153 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10155 memset(&locked_rect, 0, sizeof(locked_rect));
10156 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
10157 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10158 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
10159 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
10160 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10162 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
10163 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
10164 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
10165 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
10167 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
10168 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
10169 scale = 2.0;
10170 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
10171 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
10172 offset = 0.1;
10173 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
10174 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
10176 hr = IDirect3DDevice9_BeginScene(device);
10177 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10178 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
10179 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10180 hr = IDirect3DDevice9_EndScene(device);
10181 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10183 color = getPixelColor(device, 320, 240);
10184 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
10185 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
10186 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
10188 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
10189 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10190 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10192 /* Check a result scale factor > 1.0 */
10193 scale = 10;
10194 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
10195 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
10196 offset = 10;
10197 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
10198 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
10200 hr = IDirect3DDevice9_BeginScene(device);
10201 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10202 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
10203 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10204 hr = IDirect3DDevice9_EndScene(device);
10205 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10207 color = getPixelColor(device, 320, 240);
10208 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
10209 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10210 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10212 /* Check clamping in the scale factor calculation */
10213 scale = 1000;
10214 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
10215 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
10216 offset = -1;
10217 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
10218 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
10220 hr = IDirect3DDevice9_BeginScene(device);
10221 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10222 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
10223 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10224 hr = IDirect3DDevice9_EndScene(device);
10225 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10227 color = getPixelColor(device, 320, 240);
10228 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
10229 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10230 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10232 IDirect3DTexture9_Release(tex1);
10233 IDirect3DTexture9_Release(tex2);
10234 IDirect3DVertexDeclaration9_Release(vertex_declaration);
10235 refcount = IDirect3DDevice9_Release(device);
10236 ok(!refcount, "Device has %u references left.\n", refcount);
10237 done:
10238 IDirect3D9_Release(d3d);
10239 DestroyWindow(window);
10242 static void stencil_cull_test(void)
10244 IDirect3DDevice9 *device;
10245 IDirect3D9 *d3d;
10246 ULONG refcount;
10247 D3DCAPS9 caps;
10248 HWND window;
10249 HRESULT hr;
10250 static const float quad1[] =
10252 -1.0, -1.0, 0.1,
10253 0.0, -1.0, 0.1,
10254 -1.0, 0.0, 0.1,
10255 0.0, 0.0, 0.1,
10257 static const float quad2[] =
10259 0.0, -1.0, 0.1,
10260 1.0, -1.0, 0.1,
10261 0.0, 0.0, 0.1,
10262 1.0, 0.0, 0.1,
10264 static const float quad3[] =
10266 0.0, 0.0, 0.1,
10267 1.0, 0.0, 0.1,
10268 0.0, 1.0, 0.1,
10269 1.0, 1.0, 0.1,
10271 static const float quad4[] =
10273 -1.0, 0.0, 0.1,
10274 0.0, 0.0, 0.1,
10275 -1.0, 1.0, 0.1,
10276 0.0, 1.0, 0.1,
10278 struct
10280 struct vec3 position;
10281 DWORD diffuse;
10283 painter[] =
10285 {{-1.0f, -1.0f, 0.0f}, 0x00000000},
10286 {{ 1.0f, -1.0f, 0.0f}, 0x00000000},
10287 {{-1.0f, 1.0f, 0.0f}, 0x00000000},
10288 {{ 1.0f, 1.0f, 0.0f}, 0x00000000},
10290 static const WORD indices_cw[] = {0, 1, 3};
10291 static const WORD indices_ccw[] = {0, 2, 3};
10292 unsigned int i;
10293 DWORD color;
10295 window = create_window();
10296 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10297 ok(!!d3d, "Failed to create a D3D object.\n");
10298 if (!(device = create_device(d3d, window, window, TRUE)))
10300 skip("Cannot create a device with a D24S8 stencil buffer.\n");
10301 DestroyWindow(window);
10302 IDirect3D9_Release(d3d);
10303 return;
10305 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10306 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
10307 if (!(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED))
10309 skip("No two sided stencil support\n");
10310 goto cleanup;
10313 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
10314 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10315 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10316 ok(SUCCEEDED(hr), "Failed to set FVF,hr %#x.\n", hr);
10318 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10319 ok(hr == D3D_OK, "Failed to disable Z test, %#x.\n", hr);
10320 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10321 ok(hr == D3D_OK, "Failed to disable lighting, %#x.\n", hr);
10322 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
10323 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10324 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
10325 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10326 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
10327 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10328 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
10329 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10331 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
10332 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10333 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
10334 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10335 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
10336 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10338 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
10339 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10340 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
10341 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10343 /* First pass: Fill the stencil buffer with some values... */
10344 hr = IDirect3DDevice9_BeginScene(device);
10345 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10347 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
10348 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10349 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10350 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
10351 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10352 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10353 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
10354 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10356 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
10357 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10358 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
10359 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10360 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10361 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
10362 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10363 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10364 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
10365 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10367 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
10368 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10369 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10370 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
10371 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10372 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10373 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
10374 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10376 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
10377 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10378 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10379 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
10380 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10381 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10382 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
10383 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10385 hr = IDirect3DDevice9_EndScene(device);
10386 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10388 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
10389 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10390 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
10391 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10392 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
10393 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10394 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
10395 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10396 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
10397 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10398 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
10399 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10401 /* 2nd pass: Make the stencil values visible */
10402 hr = IDirect3DDevice9_BeginScene(device);
10403 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10404 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10405 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
10406 for (i = 0; i < 16; ++i)
10408 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
10409 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10411 painter[0].diffuse = (i * 16); /* Creates shades of blue */
10412 painter[1].diffuse = (i * 16);
10413 painter[2].diffuse = (i * 16);
10414 painter[3].diffuse = (i * 16);
10415 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
10416 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10418 hr = IDirect3DDevice9_EndScene(device);
10419 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10421 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
10422 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10424 color = getPixelColor(device, 160, 420);
10425 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
10426 color = getPixelColor(device, 160, 300);
10427 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
10429 color = getPixelColor(device, 480, 420);
10430 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
10431 color = getPixelColor(device, 480, 300);
10432 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
10434 color = getPixelColor(device, 160, 180);
10435 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
10436 color = getPixelColor(device, 160, 60);
10437 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
10439 color = getPixelColor(device, 480, 180);
10440 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
10441 color = getPixelColor(device, 480, 60);
10442 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
10444 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10445 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10447 cleanup:
10448 refcount = IDirect3DDevice9_Release(device);
10449 ok(!refcount, "Device has %u references left.\n", refcount);
10450 IDirect3D9_Release(d3d);
10451 DestroyWindow(window);
10454 static void test_fragment_coords(void)
10456 IDirect3DSurface9 *surface = NULL, *backbuffer;
10457 IDirect3DPixelShader9 *shader, *shader_frac;
10458 IDirect3DVertexShader9 *vshader;
10459 IDirect3DDevice9 *device;
10460 D3DLOCKED_RECT lr;
10461 IDirect3D9 *d3d;
10462 ULONG refcount;
10463 D3DCAPS9 caps;
10464 DWORD color;
10465 HWND window;
10466 HRESULT hr;
10467 DWORD *pos;
10469 static const DWORD shader_code[] =
10471 0xffff0300, /* ps_3_0 */
10472 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
10473 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
10474 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
10475 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
10476 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
10477 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
10478 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
10479 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
10480 0x0000ffff /* end */
10482 static const DWORD shader_frac_code[] =
10484 0xffff0300, /* ps_3_0 */
10485 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
10486 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
10487 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
10488 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
10489 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
10490 0x0000ffff /* end */
10492 static const DWORD vshader_code[] =
10494 0xfffe0300, /* vs_3_0 */
10495 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10496 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
10497 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
10498 0x0000ffff /* end */
10500 static const float quad[] =
10502 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
10503 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
10504 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
10505 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
10507 float constant[4] = {1.0, 0.0, 320, 240};
10509 window = create_window();
10510 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10511 ok(!!d3d, "Failed to create a D3D object.\n");
10512 if (!(device = create_device(d3d, window, window, TRUE)))
10514 skip("Failed to create a D3D device, skipping tests.\n");
10515 goto done;
10518 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10519 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
10520 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
10522 skip("No shader model 3 support, skipping tests.\n");
10523 IDirect3DDevice9_Release(device);
10524 goto done;
10527 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10528 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
10529 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
10530 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
10531 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
10532 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
10533 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
10534 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
10535 hr = IDirect3DDevice9_SetPixelShader(device, shader);
10536 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
10537 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
10538 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
10539 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10540 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
10541 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
10542 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
10544 hr = IDirect3DDevice9_BeginScene(device);
10545 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10546 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
10547 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
10548 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
10549 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10550 hr = IDirect3DDevice9_EndScene(device);
10551 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10553 /* This has to be pixel exact */
10554 color = getPixelColor(device, 319, 239);
10555 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
10556 color = getPixelColor(device, 320, 239);
10557 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
10558 color = getPixelColor(device, 319, 240);
10559 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
10560 color = getPixelColor(device, 320, 240);
10561 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
10562 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10564 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
10565 &surface, NULL);
10566 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
10567 hr = IDirect3DDevice9_BeginScene(device);
10568 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10569 constant[2] = 16; constant[3] = 16;
10570 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
10571 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
10572 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
10573 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10574 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
10575 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10576 hr = IDirect3DDevice9_EndScene(device);
10577 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10579 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
10580 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
10582 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
10583 color = *pos & 0x00ffffff;
10584 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
10585 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
10586 color = *pos & 0x00ffffff;
10587 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
10588 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
10589 color = *pos & 0x00ffffff;
10590 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
10591 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
10592 color = *pos & 0x00ffffff;
10593 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
10595 hr = IDirect3DSurface9_UnlockRect(surface);
10596 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
10598 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
10599 * have full control over the multisampling setting inside this test
10601 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
10602 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
10603 hr = IDirect3DDevice9_BeginScene(device);
10604 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10605 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
10606 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
10607 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
10608 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10609 hr = IDirect3DDevice9_EndScene(device);
10610 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10612 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10613 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
10615 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
10616 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
10618 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
10619 color = *pos & 0x00ffffff;
10620 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
10622 hr = IDirect3DSurface9_UnlockRect(surface);
10623 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
10625 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
10626 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
10627 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10628 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
10629 IDirect3DPixelShader9_Release(shader);
10630 IDirect3DPixelShader9_Release(shader_frac);
10631 IDirect3DVertexShader9_Release(vshader);
10632 if(surface) IDirect3DSurface9_Release(surface);
10633 IDirect3DSurface9_Release(backbuffer);
10634 refcount = IDirect3DDevice9_Release(device);
10635 ok(!refcount, "Device has %u references left.\n", refcount);
10636 done:
10637 IDirect3D9_Release(d3d);
10638 DestroyWindow(window);
10641 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
10643 D3DCOLOR color;
10645 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
10646 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
10647 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
10648 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
10649 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
10651 ++r;
10652 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
10653 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
10654 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
10655 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
10656 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
10658 return TRUE;
10661 static void test_pointsize(void)
10663 static const float a = 1.0f, b = 1.0f, c = 1.0f;
10664 float ptsize, ptsizemax_orig, ptsizemin_orig;
10665 IDirect3DSurface9 *rt, *backbuffer;
10666 IDirect3DTexture9 *tex1, *tex2;
10667 IDirect3DDevice9 *device;
10668 IDirect3DVertexShader9 *vs;
10669 IDirect3DPixelShader9 *ps;
10670 D3DLOCKED_RECT lr;
10671 IDirect3D9 *d3d;
10672 D3DCOLOR color;
10673 ULONG refcount;
10674 D3DCAPS9 caps;
10675 HWND window;
10676 HRESULT hr;
10677 unsigned int i, j;
10679 static const RECT rect = {0, 0, 128, 128};
10680 static const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000, 0x00000000, 0x00000000};
10681 static const DWORD tex2_data[4] = {0x00000000, 0x0000ff00, 0x00000000, 0x0000ff00};
10682 static const float vertices[] =
10684 64.0f, 64.0f, 0.1f,
10685 128.0f, 64.0f, 0.1f,
10686 192.0f, 64.0f, 0.1f,
10687 256.0f, 64.0f, 0.1f,
10688 320.0f, 64.0f, 0.1f,
10689 384.0f, 64.0f, 0.1f,
10690 448.0f, 64.0f, 0.1f,
10691 512.0f, 64.0f, 0.1f,
10693 static const struct
10695 float x, y, z;
10696 float point_size;
10698 vertex_pointsize = {64.0f, 64.0f, 0.1f, 48.0f},
10699 vertex_pointsize_scaled = {64.0f, 64.0f, 0.1f, 24.0f},
10700 vertex_pointsize_zero = {64.0f, 64.0f, 0.1f, 0.0f};
10701 /* Writing a texture coordinate from the shader is technically unnecessary, but is required
10702 * to make Windows AMD r500 drivers work. Without it, texture coordinates in the pixel
10703 * shaders are 0. */
10704 static const DWORD vshader_code[] =
10706 0xfffe0101, /* vs_1_1 */
10707 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10708 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10709 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10710 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10711 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
10712 0x00000001, 0xe00f0000, 0x90e40000, /* mov oT0, v0 */
10713 0x00000001, 0xe00f0001, 0x90e40000, /* mov oT1, v0 */
10714 0x0000ffff
10716 static const DWORD vshader_psize_code[] =
10718 0xfffe0101, /* vs_1_1 */
10719 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10720 0x0000001f, 0x80000004, 0x900f0001, /* dcl_psize v1 */
10721 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10722 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10723 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10724 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
10725 0x00000001, 0xc00f0002, 0x90000001, /* mov oPts, v1.x */
10726 0x00000001, 0xe00f0000, 0x90e40000, /* mov oT0, v0 */
10727 0x00000001, 0xe00f0001, 0x90e40000, /* mov oT1, v0 */
10728 0x0000ffff
10730 static const DWORD pshader_code[] =
10732 0xffff0101, /* ps_1_1 */
10733 0x00000042, 0xb00f0000, /* tex t0 */
10734 0x00000042, 0xb00f0001, /* tex t1 */
10735 0x00000002, 0x800f0000, 0xb0e40000, 0xb0e40001, /* add r0, t0, t1 */
10736 0x0000ffff
10738 static const DWORD pshader2_code[] =
10740 0xffff0200, /* ps_2_0 */
10741 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
10742 0x0200001f, 0x80000000, 0xb00f0001, /* dcl t1 */
10743 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10744 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10745 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
10746 0x03000042, 0x800f0001, 0xb0e40001, 0xa0e40801, /* texld r1, t1, s1 */
10747 0x03000002, 0x800f0000, 0x80e40000, 0x80e40001, /* add r0, r0, r1 */
10748 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
10749 0x0000ffff
10751 static const DWORD pshader2_zw_code[] =
10753 0xffff0200, /* ps_2_0 */
10754 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
10755 0x0200001f, 0x80000000, 0xb00f0001, /* dcl t1 */
10756 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10757 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10758 0x02000001, 0x80030000, 0xb01b0000, /* mov r0.xy, t0.wzyx */
10759 0x02000001, 0x80030001, 0xb01b0001, /* mov r1.xy, t1.wzyx */
10760 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, /* texld r0, r0, s0 */
10761 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40801, /* texld r1, r1, s1 */
10762 0x03000002, 0x800f0000, 0x80e40000, 0x80e40001, /* add r0, r0, r1 */
10763 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
10764 0x0000ffff
10766 static const DWORD vshader3_code[] =
10768 0xfffe0300, /* vs_3_0 */
10769 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10770 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
10771 0x0200001f, 0x80000005, 0xe00f0001, /* dcl_texcoord0 o1 */
10772 0x0200001f, 0x80010005, 0xe00f0002, /* dcl_texcoord1 o2 */
10773 0x03000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10774 0x04000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10775 0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10776 0x04000004, 0xe00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad o0, v0.w, c3, r0 */
10777 0x02000001, 0xe00f0001, 0x90000000, /* mov o1, v0.x */
10778 0x02000001, 0xe00f0002, 0x90000000, /* mov o2, v0.x */
10779 0x0000ffff
10781 static const DWORD vshader3_psize_code[] =
10783 0xfffe0300, /* vs_3_0 */
10784 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10785 0x0200001f, 0x80000004, 0x90010001, /* dcl_psize v1.x */
10786 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
10787 0x0200001f, 0x80000004, 0xe00f0001, /* dcl_psize o1 */
10788 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
10789 0x0200001f, 0x80010005, 0xe00f0003, /* dcl_texcoord1 o3 */
10790 0x03000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10791 0x04000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10792 0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10793 0x04000004, 0xe00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad o0, v0.w, c3, r0 */
10794 0x02000001, 0xe00f0001, 0x90000001, /* mov o1, v1.x */
10795 0x02000001, 0xe00f0002, 0x90000000, /* mov o2, v0.x */
10796 0x02000001, 0xe00f0003, 0x90000000, /* mov o3, v0.x */
10797 0x0000ffff
10799 static const DWORD pshader3_code[] =
10801 0xffff0300, /* ps_3_0 */
10802 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
10803 0x0200001f, 0x80010005, 0x900f0001, /* dcl_texcoord1 v1 */
10804 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10805 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10806 0x03000042, 0x800f0000, 0x90e40000, 0xa0e40800, /* texld r0, v0, s0 */
10807 0x03000042, 0x800f0001, 0x90e40001, 0xa0e40801, /* texld r1, v1, s1 */
10808 0x03000002, 0x800f0800, 0x80e40000, 0x80e40001, /* add oC0, r0, r1 */
10809 0x0000ffff
10811 static const DWORD pshader3_zw_code[] =
10813 0xffff0300, /* ps_3_0 */
10814 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
10815 0x0200001f, 0x80010005, 0x900f0001, /* dcl_texcoord1 v1 */
10816 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10817 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10818 0x03000042, 0x800f0000, 0x90fe0000, 0xa0e40800, /* texld r0, v0.zw, s0 */
10819 0x03000042, 0x800f0001, 0x90fe0001, 0xa0e40801, /* texld r1, v1.zw, s1 */
10820 0x03000002, 0x800f0800, 0x80e40000, 0x80e40001, /* add oC0, r0, r1 */
10821 0x0000ffff
10823 static const struct test_shader
10825 DWORD version;
10826 const DWORD *code;
10828 novs = {0, NULL},
10829 vs1 = {D3DVS_VERSION(1, 1), vshader_code},
10830 vs1_psize = {D3DVS_VERSION(1, 1), vshader_psize_code},
10831 vs3 = {D3DVS_VERSION(3, 0), vshader3_code},
10832 vs3_psize = {D3DVS_VERSION(3, 0), vshader3_psize_code},
10833 nops = {0, NULL},
10834 ps1 = {D3DPS_VERSION(1, 1), pshader_code},
10835 ps2 = {D3DPS_VERSION(2, 0), pshader2_code},
10836 ps2_zw = {D3DPS_VERSION(2, 0), pshader2_zw_code},
10837 ps3 = {D3DPS_VERSION(3, 0), pshader3_code},
10838 ps3_zw = {D3DPS_VERSION(3, 0), pshader3_zw_code};
10839 static const struct
10841 const struct test_shader *vs;
10842 const struct test_shader *ps;
10843 DWORD accepted_fvf;
10844 unsigned int nonscaled_size, scaled_size;
10845 BOOL gives_0_0_texcoord;
10846 BOOL allow_broken;
10848 test_setups[] =
10850 {&novs, &nops, D3DFVF_XYZ, 32, 45, FALSE, FALSE},
10851 {&vs1, &ps1, D3DFVF_XYZ, 32, 32, FALSE, FALSE},
10852 {&novs, &ps1, D3DFVF_XYZ, 32, 45, FALSE, FALSE},
10853 {&vs1, &nops, D3DFVF_XYZ, 32, 32, FALSE, FALSE},
10854 {&novs, &ps2, D3DFVF_XYZ, 32, 45, FALSE, TRUE},
10855 {&novs, &ps2_zw, D3DFVF_XYZ, 32, 45, TRUE, FALSE},
10856 {&vs1, &ps2, D3DFVF_XYZ, 32, 32, FALSE, TRUE},
10857 {&vs1, &ps2_zw, D3DFVF_XYZ, 32, 32, TRUE, FALSE},
10858 {&vs3, &ps3, D3DFVF_XYZ, 32, 32, FALSE, TRUE},
10859 {&vs3, &ps3_zw, D3DFVF_XYZ, 32, 32, TRUE, FALSE},
10860 {&novs, &nops, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 33, FALSE, FALSE},
10861 {&vs1_psize, &ps1, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 24, FALSE, FALSE},
10862 {&vs3_psize, &ps3, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 24, FALSE, TRUE},
10864 static const struct
10866 BOOL zero_size;
10867 BOOL scale;
10868 BOOL override_min;
10869 DWORD fvf;
10870 const void *vertex_data;
10871 unsigned int vertex_size;
10873 tests[] =
10875 {FALSE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10876 {FALSE, TRUE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10877 {FALSE, FALSE, TRUE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10878 {TRUE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10879 {FALSE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
10880 {FALSE, TRUE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_scaled, sizeof(vertex_pointsize_scaled)},
10881 {FALSE, FALSE, TRUE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
10882 {TRUE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_zero, sizeof(vertex_pointsize_zero)},
10884 /* Transforms the coordinate system [-1.0;1.0]x[1.0;-1.0] to
10885 * [0.0;0.0]x[640.0;480.0]. Z is untouched. */
10886 D3DMATRIX matrix =
10888 2.0f / 640.0f, 0.0f, 0.0f, 0.0f,
10889 0.0f, -2.0f / 480.0f, 0.0f, 0.0f,
10890 0.0f, 0.0f, 1.0f, 0.0f,
10891 -1.0f, 1.0f, 0.0f, 1.0f,
10892 }}};
10894 window = create_window();
10895 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10896 ok(!!d3d, "Failed to create a D3D object.\n");
10897 if (!(device = create_device(d3d, window, window, TRUE)))
10899 skip("Failed to create a D3D device, skipping tests.\n");
10900 goto done;
10903 memset(&caps, 0, sizeof(caps));
10904 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10905 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
10906 if(caps.MaxPointSize < 32.0) {
10907 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
10908 IDirect3DDevice9_Release(device);
10909 goto done;
10912 /* The r500 Windows driver needs a draw with regular texture coordinates at least once during the
10913 * device's lifetime, otherwise texture coordinate generation only works for texture 0. */
10914 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
10915 ok(SUCCEEDED(hr), "Failed to set FVF, hr=%#x.\n", hr);
10916 hr = IDirect3DDevice9_BeginScene(device);
10917 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10918 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, vertices, sizeof(float) * 5);
10919 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10920 hr = IDirect3DDevice9_EndScene(device);
10921 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10923 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10924 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
10925 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10926 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
10927 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
10928 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
10929 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10930 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
10932 hr = IDirect3DDevice9_BeginScene(device);
10933 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10935 ptsize = 15.0f;
10936 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10937 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10938 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
10939 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10941 ptsize = 31.0f;
10942 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10943 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10944 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
10945 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10947 ptsize = 30.75f;
10948 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10949 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10950 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
10951 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10953 if (caps.MaxPointSize >= 63.0f)
10955 ptsize = 63.0f;
10956 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10957 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10958 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
10959 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10961 ptsize = 62.75f;
10962 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10963 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10964 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
10965 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10968 ptsize = 1.0f;
10969 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10970 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10971 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
10972 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10974 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *)&ptsizemax_orig);
10975 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
10976 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *)&ptsizemin_orig);
10977 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
10979 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
10980 ptsize = 15.0f;
10981 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10982 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10983 ptsize = 1.0f;
10984 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsize);
10985 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10986 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
10987 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10989 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsizemax_orig);
10990 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10992 /* pointsize < pointsize_min < pointsize_max?
10993 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
10994 ptsize = 1.0f;
10995 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10996 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10997 ptsize = 15.0f;
10998 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
10999 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11000 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
11001 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11003 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsizemin_orig);
11004 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11006 hr = IDirect3DDevice9_EndScene(device);
11007 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11009 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
11010 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
11011 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
11013 if (caps.MaxPointSize >= 63.0)
11015 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
11016 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
11019 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
11020 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
11021 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
11022 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
11023 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
11025 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11027 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
11028 * generates texture coordinates for the point(result: Yes, it does)
11030 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
11031 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
11032 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
11034 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11035 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
11037 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
11038 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
11039 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
11040 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
11041 memset(&lr, 0, sizeof(lr));
11042 hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
11043 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
11044 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
11045 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
11046 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
11047 memset(&lr, 0, sizeof(lr));
11048 hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
11049 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
11050 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
11051 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
11052 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
11053 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
11054 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
11055 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
11056 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
11057 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11058 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
11059 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
11060 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
11061 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
11062 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
11063 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
11064 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
11065 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
11066 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
11068 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
11069 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
11070 ptsize = 32.0;
11071 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
11072 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
11074 hr = IDirect3DDevice9_BeginScene(device);
11075 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11076 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
11077 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11078 hr = IDirect3DDevice9_EndScene(device);
11079 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11081 color = getPixelColor(device, 64-4, 64-4);
11082 ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
11083 color = getPixelColor(device, 64-4, 64+4);
11084 ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
11085 color = getPixelColor(device, 64+4, 64+4);
11086 ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
11087 color = getPixelColor(device, 64+4, 64-4);
11088 ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
11089 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11091 U(matrix).m[0][0] = 1.0f / 64.0f;
11092 U(matrix).m[1][1] = -1.0f / 64.0f;
11093 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
11094 ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
11096 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11097 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11099 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
11100 D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
11101 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11103 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_A, *(DWORD *)&a);
11104 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
11105 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_B, *(DWORD *)&b);
11106 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
11107 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_C, *(DWORD *)&c);
11108 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
11109 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
11111 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, &S(U(matrix))._11, 4);
11112 ok(SUCCEEDED(hr), "Failed to set vertex shader constants, hr %#x.\n", hr);
11115 if (caps.MaxPointSize < 63.0f)
11117 skip("MaxPointSize %f < 63.0, skipping some tests.\n", caps.MaxPointSize);
11118 goto cleanup;
11121 for (i = 0; i < sizeof(test_setups) / sizeof(test_setups[0]); ++i)
11123 if (caps.VertexShaderVersion < test_setups[i].vs->version
11124 || caps.PixelShaderVersion < test_setups[i].ps->version)
11126 skip("Vertex / pixel shader version not supported, skipping test.\n");
11127 continue;
11129 if (test_setups[i].vs->code)
11131 hr = IDirect3DDevice9_CreateVertexShader(device, test_setups[i].vs->code, &vs);
11132 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
11134 else
11136 vs = NULL;
11138 if (test_setups[i].ps->code)
11140 hr = IDirect3DDevice9_CreatePixelShader(device, test_setups[i].ps->code, &ps);
11141 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
11143 else
11145 ps = NULL;
11148 hr = IDirect3DDevice9_SetVertexShader(device, vs);
11149 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
11150 hr = IDirect3DDevice9_SetPixelShader(device, ps);
11151 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
11153 for (j = 0; j < sizeof(tests) / sizeof(tests[0]); ++j)
11155 BOOL allow_broken = test_setups[i].allow_broken;
11156 unsigned int size = tests[j].override_min ? 63 : tests[j].zero_size ? 0 : tests[j].scale
11157 ? test_setups[i].scaled_size : test_setups[i].nonscaled_size;
11159 if (test_setups[i].accepted_fvf != tests[j].fvf)
11160 continue;
11162 ptsize = tests[j].zero_size ? 0.0f : 32.0f;
11163 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
11164 ok(SUCCEEDED(hr), "Failed to set pointsize, hr %#x.\n", hr);
11166 ptsize = tests[j].override_min ? 63.0f : tests[j].zero_size ? 0.0f : ptsizemin_orig;
11167 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
11168 ok(SUCCEEDED(hr), "Failed to set minimum pointsize, hr %#x.\n", hr);
11170 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALEENABLE, tests[j].scale);
11171 ok(SUCCEEDED(hr), "Failed setting point scale state, hr %#x.\n", hr);
11173 hr = IDirect3DDevice9_SetFVF(device, tests[j].fvf);
11174 ok(SUCCEEDED(hr), "Failed setting FVF, hr %#x.\n", hr);
11176 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11177 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11178 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
11179 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
11181 hr = IDirect3DDevice9_BeginScene(device);
11182 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11183 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1,
11184 tests[j].vertex_data, tests[j].vertex_size);
11185 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11186 hr = IDirect3DDevice9_EndScene(device);
11187 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11189 hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
11190 ok(SUCCEEDED(hr), "Failed to blit, hr %#x.\n", hr);
11191 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11192 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11194 if (tests[j].zero_size)
11196 /* Technically 0 pointsize is undefined in OpenGL but in practice it seems like
11197 * it does the "useful" thing on all the drivers I tried. */
11198 /* On WARP it does draw some pixels, most of the time. */
11199 color = getPixelColor(device, 64, 64);
11200 ok(color_match(color, 0x0000ffff, 0)
11201 || broken(color_match(color, 0x00ff0000, 0))
11202 || broken(color_match(color, 0x00ffff00, 0))
11203 || broken(color_match(color, 0x00000000, 0))
11204 || broken(color_match(color, 0x0000ff00, 0)),
11205 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
11207 else
11209 struct surface_readback rb;
11211 get_rt_readback(backbuffer, &rb);
11212 /* On AMD apparently only the first texcoord is modified by the point coordinates
11213 * when using SM2/3 pixel shaders. */
11214 color = get_readback_color(&rb, 64 - size / 2 + 1, 64 - size / 2 + 1);
11215 ok(color_match(color, 0x00ff0000, 0),
11216 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
11217 color = get_readback_color(&rb, 64 + size / 2 - 1, 64 - size / 2 + 1);
11218 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x00ffff00, 0)
11219 || (allow_broken && broken(color_match(color, 0x00ff0000, 0))),
11220 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
11221 color = get_readback_color(&rb, 64 - size / 2 + 1, 64 + size / 2 - 1);
11222 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x00000000, 0),
11223 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
11224 color = get_readback_color(&rb, 64 + size / 2 - 1, 64 + size / 2 - 1);
11225 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x0000ff00, 0)
11226 || (allow_broken && broken(color_match(color, 0x00000000, 0))),
11227 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
11229 color = get_readback_color(&rb, 64 - size / 2 - 1, 64 - size / 2 - 1);
11230 ok(color_match(color, 0xff00ffff, 0),
11231 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
11232 color = get_readback_color(&rb, 64 + size / 2 + 1, 64 - size / 2 - 1);
11233 ok(color_match(color, 0xff00ffff, 0),
11234 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
11235 color = get_readback_color(&rb, 64 - size / 2 - 1, 64 + size / 2 + 1);
11236 ok(color_match(color, 0xff00ffff, 0),
11237 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
11238 color = get_readback_color(&rb, 64 + size / 2 + 1, 64 + size / 2 + 1);
11239 ok(color_match(color, 0xff00ffff, 0),
11240 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
11242 release_surface_readback(&rb);
11245 IDirect3DDevice9_SetVertexShader(device, NULL);
11246 IDirect3DDevice9_SetPixelShader(device, NULL);
11247 if (vs)
11248 IDirect3DVertexShader9_Release(vs);
11249 if (ps)
11250 IDirect3DVertexShader9_Release(ps);
11253 cleanup:
11254 IDirect3DSurface9_Release(backbuffer);
11255 IDirect3DSurface9_Release(rt);
11257 IDirect3DTexture9_Release(tex1);
11258 IDirect3DTexture9_Release(tex2);
11259 refcount = IDirect3DDevice9_Release(device);
11260 ok(!refcount, "Device has %u references left.\n", refcount);
11261 done:
11262 IDirect3D9_Release(d3d);
11263 DestroyWindow(window);
11266 static void multiple_rendertargets_test(void)
11268 IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
11269 IDirect3DPixelShader9 *ps1, *ps2;
11270 IDirect3DTexture9 *tex1, *tex2;
11271 IDirect3DVertexShader9 *vs;
11272 IDirect3DDevice9 *device;
11273 IDirect3D9 *d3d;
11274 ULONG refcount;
11275 D3DCAPS9 caps;
11276 DWORD color;
11277 HWND window;
11278 HRESULT hr;
11279 UINT i, j;
11281 static const DWORD vshader_code[] =
11283 0xfffe0300, /* vs_3_0 */
11284 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11285 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
11286 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
11287 0x0000ffff /* end */
11289 static const DWORD pshader_code1[] =
11291 0xffff0300, /* ps_3_0 */
11292 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
11293 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
11294 0x0000ffff /* end */
11296 static const DWORD pshader_code2[] =
11298 0xffff0300, /* ps_3_0 */
11299 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
11300 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
11301 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
11302 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
11303 0x0000ffff /* end */
11305 static const float quad[] =
11307 -1.0f, -1.0f, 0.1f,
11308 -1.0f, 1.0f, 0.1f,
11309 1.0f, -1.0f, 0.1f,
11310 1.0f, 1.0f, 0.1f,
11312 static const float texquad[] =
11314 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
11315 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
11316 0.0f, -1.0f, 0.1f, 1.0f, 0.0f,
11317 0.0f, 1.0f, 0.1f, 1.0f, 1.0f,
11319 0.0f, -1.0f, 0.1f, 0.0f, 0.0f,
11320 0.0f, 1.0f, 0.1f, 0.0f, 1.0f,
11321 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
11322 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
11325 window = create_window();
11326 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11327 ok(!!d3d, "Failed to create a D3D object.\n");
11328 if (!(device = create_device(d3d, window, window, TRUE)))
11330 skip("Failed to create a D3D device, skipping tests.\n");
11331 goto done;
11334 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11335 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
11336 if (caps.NumSimultaneousRTs < 2)
11338 skip("Only 1 simultaneous render target supported, skipping MRT test.\n");
11339 IDirect3DDevice9_Release(device);
11340 goto done;
11342 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
11344 skip("No shader model 3 support, skipping tests.\n");
11345 IDirect3DDevice9_Release(device);
11346 goto done;
11349 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
11350 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
11352 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
11353 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
11354 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
11356 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
11357 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
11358 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
11359 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
11360 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
11361 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
11362 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
11363 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
11364 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code1, &ps1);
11365 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
11366 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code2, &ps2);
11367 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
11369 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
11370 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
11371 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
11372 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
11373 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
11374 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
11376 hr = IDirect3DDevice9_SetVertexShader(device, vs);
11377 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
11378 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
11379 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11380 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
11381 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11382 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
11383 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
11385 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
11386 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
11387 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
11388 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11389 color = getPixelColorFromSurface(readback, 8, 8);
11390 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
11391 "Expected color 0x000000ff, got 0x%08x.\n", color);
11392 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
11393 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11394 color = getPixelColorFromSurface(readback, 8, 8);
11395 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
11396 "Expected color 0x000000ff, got 0x%08x.\n", color);
11398 /* Render targets not written by the pixel shader should be unmodified. */
11399 hr = IDirect3DDevice9_SetPixelShader(device, ps1);
11400 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
11401 hr = IDirect3DDevice9_BeginScene(device);
11402 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11403 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
11404 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11405 hr = IDirect3DDevice9_EndScene(device);
11406 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11407 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
11408 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11409 color = getPixelColorFromSurface(readback, 8, 8);
11410 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
11411 "Expected color 0xff00ff00, got 0x%08x.\n", color);
11412 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
11413 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11414 for (i = 6; i < 10; ++i)
11416 for (j = 6; j < 10; ++j)
11418 color = getPixelColorFromSurface(readback, j, i);
11419 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
11420 "Expected color 0xff0000ff, got 0x%08x at %u, %u.\n", color, j, i);
11424 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
11425 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
11426 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
11427 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11428 color = getPixelColorFromSurface(readback, 8, 8);
11429 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
11430 "Expected color 0x0000ff00, got 0x%08x.\n", color);
11431 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
11432 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11433 color = getPixelColorFromSurface(readback, 8, 8);
11434 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
11435 "Expected color 0x0000ff00, got 0x%08x.\n", color);
11437 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
11438 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
11440 hr = IDirect3DDevice9_BeginScene(device);
11441 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11443 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
11444 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11446 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11447 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11448 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11449 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
11450 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11451 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
11452 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
11453 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11454 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
11455 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11456 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11457 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
11459 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
11460 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
11461 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
11462 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11464 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
11465 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
11466 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
11467 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11469 hr = IDirect3DDevice9_EndScene(device);
11470 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11472 color = getPixelColor(device, 160, 240);
11473 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
11474 color = getPixelColor(device, 480, 240);
11475 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
11476 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11478 IDirect3DPixelShader9_Release(ps2);
11479 IDirect3DPixelShader9_Release(ps1);
11480 IDirect3DVertexShader9_Release(vs);
11481 IDirect3DTexture9_Release(tex1);
11482 IDirect3DTexture9_Release(tex2);
11483 IDirect3DSurface9_Release(surf1);
11484 IDirect3DSurface9_Release(surf2);
11485 IDirect3DSurface9_Release(backbuf);
11486 IDirect3DSurface9_Release(readback);
11487 refcount = IDirect3DDevice9_Release(device);
11488 ok(!refcount, "Device has %u references left.\n", refcount);
11489 done:
11490 IDirect3D9_Release(d3d);
11491 DestroyWindow(window);
11494 static void pixelshader_blending_test(void)
11496 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
11497 IDirect3DTexture9 *offscreenTexture = NULL;
11498 IDirect3DDevice9 *device;
11499 IDirect3D9 *d3d;
11500 ULONG refcount;
11501 int fmt_index;
11502 DWORD color;
11503 HWND window;
11504 HRESULT hr;
11506 static const struct
11508 const char *fmtName;
11509 D3DFORMAT textureFormat;
11510 D3DCOLOR resultColorBlending;
11511 D3DCOLOR resultColorNoBlending;
11513 test_formats[] =
11515 {"D3DFMT_G16R16", D3DFMT_G16R16, 0x001820ff, 0x002010ff},
11516 {"D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff},
11517 {"D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001820ff, 0x002010ff},
11518 {"D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00182000, 0x00201000},
11519 {"D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff},
11520 {"D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001820ff, 0x002010ff},
11521 {"D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00182000, 0x00201000},
11522 {"D3DFMT_L8", D3DFMT_L8, 0x00181818, 0x00202020},
11524 static const float quad[][5] =
11526 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
11527 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
11528 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
11529 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
11531 static const struct
11533 struct vec3 position;
11534 DWORD diffuse;
11536 quad1[] =
11538 {{-1.0f, -1.0f, 0.1f}, 0x80103000},
11539 {{-1.0f, 1.0f, 0.1f}, 0x80103000},
11540 {{ 1.0f, -1.0f, 0.1f}, 0x80103000},
11541 {{ 1.0f, 1.0f, 0.1f}, 0x80103000},
11543 quad2[] =
11545 {{-1.0f, -1.0f, 0.1f}, 0x80201000},
11546 {{-1.0f, 1.0f, 0.1f}, 0x80201000},
11547 {{ 1.0f, -1.0f, 0.1f}, 0x80201000},
11548 {{ 1.0f, 1.0f, 0.1f}, 0x80201000},
11551 window = create_window();
11552 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11553 ok(!!d3d, "Failed to create a D3D object.\n");
11554 if (!(device = create_device(d3d, window, window, TRUE)))
11556 skip("Failed to create a D3D device, skipping tests.\n");
11557 goto done;
11560 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
11561 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
11563 for (fmt_index = 0; fmt_index < sizeof(test_formats) / sizeof(*test_formats); ++fmt_index)
11565 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
11567 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11568 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
11570 skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
11571 continue;
11574 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
11575 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
11577 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
11578 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
11579 if(!offscreenTexture) {
11580 continue;
11583 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
11584 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
11585 if(!offscreen) {
11586 continue;
11589 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11590 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
11592 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11593 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11594 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
11595 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11596 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11597 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
11598 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11599 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
11600 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11601 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
11603 /* Below we will draw two quads with different colors and try to blend
11604 * them together. The result color is compared with the expected
11605 * outcome. */
11606 hr = IDirect3DDevice9_BeginScene(device);
11607 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11609 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
11610 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11611 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 1.0f, 0);
11612 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
11614 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
11615 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11617 /* Draw a quad using color 0x0010200. */
11618 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
11619 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11620 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
11621 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11622 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
11623 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11625 /* Draw a quad using color 0x0020100. */
11626 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
11627 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11628 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
11629 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11630 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
11631 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11633 /* We don't want to blend the result on the backbuffer. */
11634 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
11635 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11637 /* Prepare rendering the 'blended' texture quad to the backbuffer. */
11638 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11639 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11640 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)offscreenTexture);
11641 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
11643 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11644 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
11646 /* This time with the texture. */
11647 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
11648 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11650 hr = IDirect3DDevice9_EndScene(device);
11651 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11653 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11654 D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK)
11656 /* Compare the color of the center quad with our expectation. */
11657 color = getPixelColor(device, 320, 240);
11658 ok(color_match(color, test_formats[fmt_index].resultColorBlending, 1),
11659 "Offscreen failed for %s: Got color 0x%08x, expected 0x%08x.\n",
11660 test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
11662 else
11664 /* No pixel shader blending is supported so expect garbage. The
11665 * type of 'garbage' depends on the driver version and OS. E.g. on
11666 * G16R16 ATI reports (on old r9600 drivers) 0x00ffffff and on
11667 * modern ones 0x002010ff which is also what NVIDIA reports. On
11668 * Vista NVIDIA seems to report 0x00ffffff on Geforce7 cards. */
11669 color = getPixelColor(device, 320, 240);
11670 ok((color == 0x00ffffff) || (color == test_formats[fmt_index].resultColorNoBlending),
11671 "Offscreen failed for %s: Got unexpected color 0x%08x, expected no color blending.\n",
11672 test_formats[fmt_index].fmtName, color);
11674 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11676 IDirect3DDevice9_SetTexture(device, 0, NULL);
11677 if(offscreenTexture) {
11678 IDirect3DTexture9_Release(offscreenTexture);
11680 if(offscreen) {
11681 IDirect3DSurface9_Release(offscreen);
11685 IDirect3DSurface9_Release(backbuffer);
11686 refcount = IDirect3DDevice9_Release(device);
11687 ok(!refcount, "Device has %u references left.\n", refcount);
11688 done:
11689 IDirect3D9_Release(d3d);
11690 DestroyWindow(window);
11693 static void tssargtemp_test(void)
11695 IDirect3DDevice9 *device;
11696 IDirect3D9 *d3d;
11697 D3DCOLOR color;
11698 ULONG refcount;
11699 D3DCAPS9 caps;
11700 HWND window;
11701 HRESULT hr;
11703 static const struct
11705 struct vec3 position;
11706 DWORD diffuse;
11708 quad[] =
11710 {{-1.0f, -1.0f, 0.1f}, 0x00ff0000},
11711 {{-1.0f, 1.0f, 0.1f}, 0x00ff0000},
11712 {{ 1.0f, -1.0f, 0.1f}, 0x00ff0000},
11713 {{ 1.0f, 1.0f, 0.1f}, 0x00ff0000},
11716 window = create_window();
11717 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11718 ok(!!d3d, "Failed to create a D3D object.\n");
11719 if (!(device = create_device(d3d, window, window, TRUE)))
11721 skip("Failed to create a D3D device, skipping tests.\n");
11722 goto done;
11725 memset(&caps, 0, sizeof(caps));
11726 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11727 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
11728 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
11729 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
11730 IDirect3DDevice9_Release(device);
11731 goto done;
11734 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
11735 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11737 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11738 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11739 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
11740 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11742 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11743 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11744 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
11745 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11746 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
11747 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11749 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
11750 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11751 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
11752 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11753 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
11754 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11756 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
11757 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11759 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
11760 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
11761 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11762 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
11763 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11764 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
11766 hr = IDirect3DDevice9_BeginScene(device);
11767 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11768 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
11769 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11770 hr = IDirect3DDevice9_EndScene(device);
11771 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11773 color = getPixelColor(device, 320, 240);
11774 ok(color == 0x00ffff00, "TSSARGTEMP test returned color 0x%08x, expected 0x00ffff00\n", color);
11775 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11777 refcount = IDirect3DDevice9_Release(device);
11778 ok(!refcount, "Device has %u references left.\n", refcount);
11779 done:
11780 IDirect3D9_Release(d3d);
11781 DestroyWindow(window);
11784 /* Drawing Indexed Geometry with instances*/
11785 static void stream_test(void)
11787 IDirect3DVertexDeclaration9 *pDecl = NULL;
11788 IDirect3DVertexShader9 *shader = NULL;
11789 IDirect3DVertexBuffer9 *vb3 = NULL;
11790 IDirect3DVertexBuffer9 *vb2 = NULL;
11791 IDirect3DVertexBuffer9 *vb = NULL;
11792 IDirect3DIndexBuffer9 *ib = NULL;
11793 IDirect3DDevice9 *device;
11794 IDirect3D9 *d3d;
11795 ULONG refcount;
11796 D3DCAPS9 caps;
11797 DWORD color;
11798 HWND window;
11799 unsigned i;
11800 HRESULT hr;
11801 BYTE *data;
11802 DWORD ind;
11804 static const struct testdata
11806 DWORD idxVertex; /* number of instances in the first stream */
11807 DWORD idxColor; /* number of instances in the second stream */
11808 DWORD idxInstance; /* should be 1 ?? */
11809 DWORD color1; /* color 1 instance */
11810 DWORD color2; /* color 2 instance */
11811 DWORD color3; /* color 3 instance */
11812 DWORD color4; /* color 4 instance */
11813 WORD strVertex; /* specify which stream to use 0-2*/
11814 WORD strColor;
11815 WORD strInstance;
11816 DWORD explicit_zero_freq;
11818 testcases[]=
11820 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
11821 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
11822 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
11823 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
11824 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 4 */
11825 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
11826 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
11827 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
11828 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 8 */
11829 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 9 */
11830 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 10 */
11831 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 11 */
11833 /* The number of instances is read from stream zero, even if stream zero is not
11834 * in use. Exact behavior of this corner case depends on the presence or absence
11835 * of D3DSTREAMSOURCE_INDEXEDDATA. r500 GPUs need D3DSTREAMSOURCE_INDEXEDDATA
11836 * to be present, otherwise they disable instancing and behave like in a non-
11837 * instanced draw. Nvidia drivers do not show different behavior with or without
11838 * D3DSTREAMSOURCE_INDEXEDDATA. Note however that setting the value to 0 is not
11839 * allowed by the d3d runtime.
11841 * The meaning of (D3DSTREAMSOURCE_INDEXEDDATA | 0) is driver dependent. r500
11842 * will fall back to non-instanced drawing. Geforce 7 will draw 1 instance.
11843 * Geforce 8+ will draw nothing. */
11844 {3, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1, 1}, /* 12 */
11845 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 2, 3, 1, 2}, /* 13 */
11846 {1, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 2, 3, 1, 3}, /* 14 */
11847 {0, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 3, 1, 4}, /* 15 */
11849 static const DWORD shader_code[] =
11851 0xfffe0101, /* vs_1_1 */
11852 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11853 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
11854 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
11855 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
11856 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
11857 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
11858 0x0000ffff
11860 /* Note that this set of coordinates and instancepos[] have an implicit
11861 * w = 1.0, which is added to w = 2.0, so the perspective divide divides
11862 * x, y and z by 2. */
11863 static const float quad[][3] =
11865 {-0.5f, -0.5f, 1.1f}, /*0 */
11866 {-0.5f, 0.5f, 1.1f}, /*1 */
11867 { 0.5f, -0.5f, 1.1f}, /*2 */
11868 { 0.5f, 0.5f, 1.1f}, /*3 */
11870 static const float vertcolor[][4] =
11872 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
11873 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
11874 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
11875 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
11877 /* 4 position for 4 instances */
11878 static const float instancepos[][3] =
11880 {-0.6f,-0.6f, 0.0f},
11881 { 0.6f,-0.6f, 0.0f},
11882 { 0.6f, 0.6f, 0.0f},
11883 {-0.6f, 0.6f, 0.0f},
11885 static const short indices[] = {0, 1, 2, 2, 1, 3};
11886 D3DVERTEXELEMENT9 decl[] =
11888 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
11889 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
11890 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
11891 D3DDECL_END()
11894 window = create_window();
11895 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11896 ok(!!d3d, "Failed to create a D3D object.\n");
11897 if (!(device = create_device(d3d, window, window, TRUE)))
11899 skip("Failed to create a D3D device, skipping tests.\n");
11900 goto done;
11903 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11904 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
11905 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
11907 skip("No vs_3_0 support, skipping tests.\n");
11908 IDirect3DDevice9_Release(device);
11909 goto done;
11912 /* set the default value because it isn't done in wine? */
11913 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
11914 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11916 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
11917 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
11918 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11920 /* check wrong cases */
11921 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
11922 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11923 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11924 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11925 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
11926 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11927 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11928 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11929 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
11930 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11931 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11932 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11933 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
11934 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11935 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11936 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11937 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
11938 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11939 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11940 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11942 /* set the default value back */
11943 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
11944 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11946 /* create all VertexBuffers*/
11947 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
11948 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
11949 if(!vb) {
11950 skip("Failed to create a vertex buffer\n");
11951 IDirect3DDevice9_Release(device);
11952 goto done;
11954 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
11955 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
11956 if(!vb2) {
11957 skip("Failed to create a vertex buffer\n");
11958 goto out;
11960 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
11961 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
11962 if(!vb3) {
11963 skip("Failed to create a vertex buffer\n");
11964 goto out;
11967 /* create IndexBuffer*/
11968 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
11969 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
11970 if(!ib) {
11971 skip("Failed to create an index buffer\n");
11972 goto out;
11975 /* copy all Buffers (Vertex + Index)*/
11976 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
11977 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
11978 memcpy(data, quad, sizeof(quad));
11979 hr = IDirect3DVertexBuffer9_Unlock(vb);
11980 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
11981 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
11982 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
11983 memcpy(data, vertcolor, sizeof(vertcolor));
11984 hr = IDirect3DVertexBuffer9_Unlock(vb2);
11985 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
11986 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
11987 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
11988 memcpy(data, instancepos, sizeof(instancepos));
11989 hr = IDirect3DVertexBuffer9_Unlock(vb3);
11990 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
11991 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
11992 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
11993 memcpy(data, indices, sizeof(indices));
11994 hr = IDirect3DIndexBuffer9_Unlock(ib);
11995 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
11997 /* create VertexShader */
11998 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
11999 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
12000 if(!shader) {
12001 skip("Failed to create a vertex shader.\n");
12002 goto out;
12005 hr = IDirect3DDevice9_SetVertexShader(device, shader);
12006 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
12008 hr = IDirect3DDevice9_SetIndices(device, ib);
12009 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
12011 /* run all tests */
12012 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
12014 struct testdata act = testcases[i];
12015 decl[0].Stream = act.strVertex;
12016 decl[1].Stream = act.strColor;
12017 decl[2].Stream = act.strInstance;
12018 /* create VertexDeclarations */
12019 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
12020 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
12022 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
12023 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
12025 hr = IDirect3DDevice9_BeginScene(device);
12026 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12028 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
12029 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
12031 /* If stream 0 is unused, set the stream frequency regardless to show
12032 * that the number if instances is read from it. */
12033 if (act.strVertex && act.strColor && act.strInstance)
12035 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0,
12036 D3DSTREAMSOURCE_INDEXEDDATA | act.explicit_zero_freq);
12037 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
12040 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex,
12041 (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
12042 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
12043 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
12044 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
12046 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor,
12047 (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
12048 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
12049 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
12050 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
12052 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance,
12053 (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
12054 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
12055 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
12056 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
12058 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
12059 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12060 hr = IDirect3DDevice9_EndScene(device);
12061 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12063 /* set all StreamSource && StreamSourceFreq back to default */
12064 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
12065 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
12066 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
12067 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
12068 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
12069 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
12070 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
12071 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
12072 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
12073 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
12074 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
12075 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
12077 hr = IDirect3DVertexDeclaration9_Release(pDecl);
12078 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
12080 color = getPixelColor(device, 160, 360);
12081 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
12082 color = getPixelColor(device, 480, 360);
12083 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
12084 color = getPixelColor(device, 480, 120);
12085 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
12086 color = getPixelColor(device, 160, 120);
12087 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
12089 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12090 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
12093 out:
12094 if(vb) IDirect3DVertexBuffer9_Release(vb);
12095 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
12096 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
12097 if(ib)IDirect3DIndexBuffer9_Release(ib);
12098 if(shader)IDirect3DVertexShader9_Release(shader);
12099 refcount = IDirect3DDevice9_Release(device);
12100 ok(!refcount, "Device has %u references left.\n", refcount);
12101 done:
12102 IDirect3D9_Release(d3d);
12103 DestroyWindow(window);
12106 static void np2_stretch_rect_test(void)
12108 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
12109 IDirect3DTexture9 *dsttex = NULL;
12110 IDirect3DDevice9 *device;
12111 IDirect3D9 *d3d;
12112 D3DCOLOR color;
12113 ULONG refcount;
12114 HWND window;
12115 HRESULT hr;
12117 static const D3DRECT r1 = {0, 0, 50, 50 };
12118 static const D3DRECT r2 = {50, 0, 100, 50 };
12119 static const D3DRECT r3 = {50, 50, 100, 100};
12120 static const D3DRECT r4 = {0, 50, 50, 100};
12121 static const float quad[] =
12123 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
12124 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
12125 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
12126 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
12129 window = create_window();
12130 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12131 ok(!!d3d, "Failed to create a D3D object.\n");
12132 if (!(device = create_device(d3d, window, window, TRUE)))
12134 skip("Failed to create a D3D device, skipping tests.\n");
12135 goto done;
12138 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
12139 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
12141 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
12142 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
12143 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
12144 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
12146 if(!src || !dsttex) {
12147 skip("One or more test resources could not be created\n");
12148 goto cleanup;
12151 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
12152 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
12154 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
12155 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
12157 /* Clear the StretchRect destination for debugging */
12158 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
12159 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
12160 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
12161 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
12163 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
12164 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
12166 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
12167 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
12168 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
12169 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
12170 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
12171 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
12172 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
12173 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
12175 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
12176 * the target -> texture GL blit path
12178 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
12179 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
12180 IDirect3DSurface9_Release(dst);
12182 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
12183 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
12185 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
12186 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
12187 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
12188 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
12189 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12190 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
12191 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12192 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
12194 hr = IDirect3DDevice9_BeginScene(device);
12195 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12196 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
12197 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12198 hr = IDirect3DDevice9_EndScene(device);
12199 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12201 color = getPixelColor(device, 160, 360);
12202 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
12203 color = getPixelColor(device, 480, 360);
12204 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
12205 color = getPixelColor(device, 480, 120);
12206 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
12207 color = getPixelColor(device, 160, 120);
12208 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
12209 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12210 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
12212 cleanup:
12213 if(src) IDirect3DSurface9_Release(src);
12214 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
12215 if(dsttex) IDirect3DTexture9_Release(dsttex);
12216 refcount = IDirect3DDevice9_Release(device);
12217 ok(!refcount, "Device has %u references left.\n", refcount);
12218 done:
12219 IDirect3D9_Release(d3d);
12220 DestroyWindow(window);
12223 static void texop_test(void)
12225 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
12226 IDirect3DTexture9 *texture = NULL;
12227 D3DLOCKED_RECT locked_rect;
12228 IDirect3DDevice9 *device;
12229 IDirect3D9 *d3d;
12230 D3DCOLOR color;
12231 ULONG refcount;
12232 D3DCAPS9 caps;
12233 HWND window;
12234 HRESULT hr;
12235 unsigned i;
12237 static const struct {
12238 float x, y, z;
12239 float s, t;
12240 D3DCOLOR diffuse;
12241 } quad[] = {
12242 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
12243 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
12244 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
12245 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
12248 static const D3DVERTEXELEMENT9 decl_elements[] = {
12249 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
12250 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
12251 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
12252 D3DDECL_END()
12255 static const struct {
12256 D3DTEXTUREOP op;
12257 const char *name;
12258 DWORD caps_flag;
12259 D3DCOLOR result;
12260 } test_data[] = {
12261 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
12262 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
12263 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
12264 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
12265 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
12266 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
12267 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
12268 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
12269 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
12270 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
12271 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
12272 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
12273 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
12274 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
12275 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
12276 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
12277 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
12278 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
12279 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
12280 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
12281 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT3", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
12282 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
12283 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
12286 window = create_window();
12287 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12288 ok(!!d3d, "Failed to create a D3D object.\n");
12289 if (!(device = create_device(d3d, window, window, TRUE)))
12291 skip("Failed to create a D3D device, skipping tests.\n");
12292 goto done;
12295 memset(&caps, 0, sizeof(caps));
12296 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12297 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
12299 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
12300 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
12301 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
12302 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
12304 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
12305 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
12306 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
12307 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
12308 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
12309 hr = IDirect3DTexture9_UnlockRect(texture, 0);
12310 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
12311 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
12312 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
12314 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
12315 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12316 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12317 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12318 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12319 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12321 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
12322 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12324 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12325 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12326 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
12327 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12328 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
12329 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12331 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12332 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12334 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
12336 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
12338 skip("tex operation %s not supported\n", test_data[i].name);
12339 continue;
12342 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
12343 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
12345 hr = IDirect3DDevice9_BeginScene(device);
12346 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
12348 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12349 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
12351 hr = IDirect3DDevice9_EndScene(device);
12352 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
12354 color = getPixelColor(device, 320, 240);
12355 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
12356 test_data[i].name, color, test_data[i].result);
12358 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12359 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12362 IDirect3DTexture9_Release(texture);
12363 IDirect3DVertexDeclaration9_Release(vertex_declaration);
12364 refcount = IDirect3DDevice9_Release(device);
12365 ok(!refcount, "Device has %u references left.\n", refcount);
12366 done:
12367 IDirect3D9_Release(d3d);
12368 DestroyWindow(window);
12371 static void yuv_color_test(void)
12373 HRESULT hr;
12374 IDirect3DSurface9 *surface, *target;
12375 unsigned int i;
12376 D3DLOCKED_RECT lr;
12377 IDirect3D9 *d3d;
12378 D3DCOLOR color;
12379 D3DFORMAT skip_once = D3DFMT_UNKNOWN;
12380 IDirect3DDevice9 *device;
12381 D3DSURFACE_DESC desc;
12382 ULONG refcount;
12383 HWND window;
12385 static const struct
12387 DWORD in;
12388 D3DFORMAT format;
12389 const char *fmt_string;
12390 D3DCOLOR left, right;
12392 test_data[] =
12394 {0x00000000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00008700, 0x00008700},
12395 {0xff000000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00008700, 0x004bff1c},
12396 {0x00ff0000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b30000, 0x00b30000},
12397 {0x0000ff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bff1c, 0x00008700},
12398 {0x000000ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000030e1, 0x000030e1},
12399 {0xffff0000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b30000, 0x00ffd01c},
12400 {0xff00ff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bff1c, 0x004bff1c},
12401 {0xff0000ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000030e1, 0x004bffff},
12402 {0x00ffff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffd01c, 0x00b30000},
12403 {0x00ff00ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b300e1, 0x00b300e1},
12404 {0x0000ffff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bffff, 0x001030e1},
12405 {0xffffff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffd01c, 0x00ffd01c},
12406 {0xffff00ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b300e1, 0x00ff79ff},
12407 {0xffffffff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ff79ff, 0x00ff79ff},
12408 {0x4cff4c54, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ff0000, 0x00ff0000},
12409 {0x00800080, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00000000, 0x00000000},
12410 {0xff80ff80, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffffff, 0x00ffffff},
12411 {0x1c6b1cff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000000fd, 0x000000fd},
12413 {0x00000000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00008700, 0x00008700},
12414 {0xff000000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b30000, 0x00b30000},
12415 {0x00ff0000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00008700, 0x004bff1c},
12416 {0x0000ff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000030e1, 0x000030e1},
12417 {0x000000ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bff1c, 0x00008700},
12418 {0xffff0000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b30000, 0x00ffd01c},
12419 {0xff00ff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b300e1, 0x00b300e1},
12420 {0xff0000ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ffd01c, 0x00b30000},
12421 {0x00ffff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000030e1, 0x004bffff},
12422 {0x00ff00ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bff1c, 0x004bff1c},
12423 {0x0000ffff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bffff, 0x000030e1},
12424 {0xffffff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b300e1, 0x00ff79ff},
12425 {0xffff00ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ffd01c, 0x00ffd01c},
12426 {0xffffffff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ff79ff, 0x00ff79ff},
12427 {0x4cff4c54, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000b8b00, 0x00b6ffa3},
12428 {0x00800080, D3DFMT_YUY2, "D3DFMT_YUY2", 0x0000ff00, 0x0000ff00},
12429 {0xff80ff80, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ff00ff, 0x00ff00ff},
12430 {0x1c6b1cff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x006dff45, 0x0000d500},
12433 window = create_window();
12434 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12435 ok(!!d3d, "Failed to create a D3D object.\n");
12436 if (!(device = create_device(d3d, window, window, TRUE)))
12438 skip("Failed to create a D3D device, skipping tests.\n");
12439 goto done;
12442 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
12443 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
12444 hr = IDirect3DSurface9_GetDesc(target, &desc);
12445 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
12447 for (i = 0; i < sizeof(test_data) / sizeof(test_data[0]); i++)
12449 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect.
12450 * Thus use StretchRect to draw the YUV surface onto the screen instead of drawPrimitive. */
12451 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
12452 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, test_data[i].format)))
12454 if (skip_once != test_data[i].format)
12456 skip("%s is not supported.\n", test_data[i].fmt_string);
12457 skip_once = test_data[i].format;
12459 continue;
12461 if (FAILED(IDirect3D9_CheckDeviceFormatConversion(d3d, 0,
12462 D3DDEVTYPE_HAL, test_data[i].format, desc.Format)))
12464 if (skip_once != test_data[i].format)
12466 skip("Driver cannot blit %s surfaces.\n", test_data[i].fmt_string);
12467 skip_once = test_data[i].format;
12469 continue;
12472 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1.
12473 * However, Nvidia Windows drivers have problems with 2x1 YUY2/UYVY surfaces, so use a 4x1 surface and
12474 * fill the second block with dummy data. If the surface has a size of 2x1, those drivers ignore the
12475 * second luminance value, resulting in an incorrect color in the right pixel. */
12476 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 1, test_data[i].format,
12477 D3DPOOL_DEFAULT, &surface, NULL);
12478 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
12481 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
12482 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
12483 ((DWORD *)lr.pBits)[0] = test_data[i].in;
12484 ((DWORD *)lr.pBits)[1] = 0x00800080;
12485 hr = IDirect3DSurface9_UnlockRect(surface);
12486 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
12488 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
12489 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
12490 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
12491 ok(SUCCEEDED(hr), "Failed to draw surface onto backbuffer, hr %#x.\n", hr);
12493 /* Some Windows drivers (mostly Nvidia, but also some VM drivers) insist on doing linear filtering
12494 * although we asked for point filtering. Be careful when reading the results and use the pixel
12495 * centers. In the future we may want to add tests for the filtered pixels as well.
12497 * Unfortunately different implementations(Windows-Nvidia and Mac-AMD tested) interpret some colors
12498 * vastly differently, so we need a max diff of 18. */
12499 color = getPixelColor(device, 1, 240);
12500 ok(color_match(color, test_data[i].left, 18),
12501 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s.\n",
12502 test_data[i].in, color, test_data[i].left, test_data[i].fmt_string);
12503 color = getPixelColor(device, 318, 240);
12504 ok(color_match(color, test_data[i].right, 18),
12505 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s.\n",
12506 test_data[i].in, color, test_data[i].right, test_data[i].fmt_string);
12507 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12508 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
12509 IDirect3DSurface9_Release(surface);
12512 IDirect3DSurface9_Release(target);
12513 refcount = IDirect3DDevice9_Release(device);
12514 ok(!refcount, "Device has %u references left.\n", refcount);
12515 done:
12516 IDirect3D9_Release(d3d);
12517 DestroyWindow(window);
12520 static void yuv_layout_test(void)
12522 HRESULT hr;
12523 IDirect3DSurface9 *surface, *target;
12524 unsigned int fmt, i, x, y;
12525 D3DFORMAT format;
12526 const char *fmt_string;
12527 D3DLOCKED_RECT lr;
12528 IDirect3D9 *d3d;
12529 D3DCOLOR color;
12530 DWORD ref_color;
12531 BYTE *buf, *chroma_buf, *u_buf, *v_buf;
12532 UINT width = 20, height = 16;
12533 IDirect3DDevice9 *device;
12534 ULONG refcount;
12535 D3DCAPS9 caps;
12536 D3DSURFACE_DESC desc;
12537 HWND window;
12539 static const struct
12541 DWORD color1, color2;
12542 DWORD rgb1, rgb2;
12544 test_data[] =
12546 { 0x000000, 0xffffff, 0x00008800, 0x00ff7dff },
12547 { 0xff0000, 0x00ffff, 0x004aff14, 0x00b800ee },
12548 { 0x00ff00, 0xff00ff, 0x000024ee, 0x00ffe114 },
12549 { 0x0000ff, 0xffff00, 0x00b80000, 0x004affff },
12550 { 0xffff00, 0x0000ff, 0x004affff, 0x00b80000 },
12551 { 0xff00ff, 0x00ff00, 0x00ffe114, 0x000024ee },
12552 { 0x00ffff, 0xff0000, 0x00b800ee, 0x004aff14 },
12553 { 0xffffff, 0x000000, 0x00ff7dff, 0x00008800 },
12556 static const struct
12558 D3DFORMAT format;
12559 const char *str;
12561 formats[] =
12563 { D3DFMT_UYVY, "D3DFMT_UYVY", },
12564 { D3DFMT_YUY2, "D3DFMT_YUY2", },
12565 { MAKEFOURCC('Y','V','1','2'), "D3DFMT_YV12", },
12566 { MAKEFOURCC('N','V','1','2'), "D3DFMT_NV12", },
12569 window = create_window();
12570 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12571 ok(!!d3d, "Failed to create a D3D object.\n");
12572 if (!(device = create_device(d3d, window, window, TRUE)))
12574 skip("Failed to create a D3D device, skipping tests.\n");
12575 goto done;
12578 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12579 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
12580 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2
12581 && !(caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL))
12583 skip("No NP2 texture support, skipping YUV texture layout test.\n");
12584 IDirect3DDevice9_Release(device);
12585 goto done;
12588 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
12589 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %#x.\n", hr);
12590 hr = IDirect3DSurface9_GetDesc(target, &desc);
12591 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
12593 for (fmt = 0; fmt < sizeof(formats) / sizeof(formats[0]); fmt++)
12595 format = formats[fmt].format;
12596 fmt_string = formats[fmt].str;
12598 /* Some (all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in
12599 * StretchRect. Thus use StretchRect to draw the YUV surface onto the screen instead
12600 * of drawPrimitive. */
12601 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
12602 D3DRTYPE_SURFACE, format) != D3D_OK)
12604 skip("%s is not supported.\n", fmt_string);
12605 continue;
12607 if (FAILED(IDirect3D9_CheckDeviceFormatConversion(d3d, 0,
12608 D3DDEVTYPE_HAL, format, desc.Format)))
12610 skip("Driver cannot blit %s surfaces.\n", fmt_string);
12611 continue;
12614 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, width, height, format, D3DPOOL_DEFAULT, &surface, NULL);
12615 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %#x.\n", hr);
12617 for (i = 0; i < sizeof(test_data) / sizeof(test_data[0]); i++)
12619 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
12620 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %#x.\n", hr);
12621 buf = lr.pBits;
12622 chroma_buf = buf + lr.Pitch * height;
12623 if (format == MAKEFOURCC('Y','V','1','2'))
12625 v_buf = chroma_buf;
12626 u_buf = chroma_buf + height / 2 * lr.Pitch/2;
12628 /* Draw the top left quarter of the screen with color1, the rest with color2 */
12629 for (y = 0; y < height; y++)
12631 for (x = 0; x < width; x += 2)
12633 DWORD color = (x < width / 2 && y < height / 2) ? test_data[i].color1 : test_data[i].color2;
12634 BYTE Y = (color >> 16) & 0xff;
12635 BYTE U = (color >> 8) & 0xff;
12636 BYTE V = (color >> 0) & 0xff;
12637 if (format == D3DFMT_UYVY)
12639 buf[y * lr.Pitch + 2 * x + 0] = U;
12640 buf[y * lr.Pitch + 2 * x + 1] = Y;
12641 buf[y * lr.Pitch + 2 * x + 2] = V;
12642 buf[y * lr.Pitch + 2 * x + 3] = Y;
12644 else if (format == D3DFMT_YUY2)
12646 buf[y * lr.Pitch + 2 * x + 0] = Y;
12647 buf[y * lr.Pitch + 2 * x + 1] = U;
12648 buf[y * lr.Pitch + 2 * x + 2] = Y;
12649 buf[y * lr.Pitch + 2 * x + 3] = V;
12651 else if (format == MAKEFOURCC('Y','V','1','2'))
12653 buf[y * lr.Pitch + x + 0] = Y;
12654 buf[y * lr.Pitch + x + 1] = Y;
12655 u_buf[(y / 2) * (lr.Pitch / 2) + (x / 2)] = U;
12656 v_buf[(y / 2) * (lr.Pitch / 2) + (x / 2)] = V;
12658 else if (format == MAKEFOURCC('N','V','1','2'))
12660 buf[y * lr.Pitch + x + 0] = Y;
12661 buf[y * lr.Pitch + x + 1] = Y;
12662 chroma_buf[(y / 2) * lr.Pitch + 2 * (x / 2) + 0] = U;
12663 chroma_buf[(y / 2) * lr.Pitch + 2 * (x / 2) + 1] = V;
12667 hr = IDirect3DSurface9_UnlockRect(surface);
12668 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %#x.\n", hr);
12670 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
12671 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %#x.\n", hr);
12672 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
12673 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %#x.\n", hr);
12675 /* Some Windows drivers (mostly Nvidia, but also some VM drivers) insist on doing linear filtering
12676 * although we asked for point filtering. To prevent running into precision problems, read at points
12677 * with some margin within each quadrant.
12679 * Unfortunately different implementations(Windows-Nvidia and Mac-AMD tested) interpret some colors
12680 * vastly differently, so we need a max diff of 18. */
12681 for (y = 0; y < 4; y++)
12683 for (x = 0; x < 4; x++)
12685 UINT xcoord = (1 + 2 * x) * 640 / 8;
12686 UINT ycoord = (1 + 2 * y) * 480 / 8;
12687 ref_color = (y < 2 && x < 2) ? test_data[i].rgb1 : test_data[i].rgb2;
12688 color = getPixelColor(device, xcoord, ycoord);
12689 ok(color_match(color, ref_color, 18),
12690 "Format %s: Got color %#x for pixel (%d/%d)/(%d/%d), pixel %d %d, expected %#x.\n",
12691 fmt_string, color, x, 4, y, 4, xcoord, ycoord, ref_color);
12694 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12696 ok(SUCCEEDED(hr), "Present failed with %#x.\n", hr);
12698 IDirect3DSurface9_Release(surface);
12701 IDirect3DSurface9_Release(target);
12702 refcount = IDirect3DDevice9_Release(device);
12703 ok(!refcount, "Device has %u references left.\n", refcount);
12704 done:
12705 IDirect3D9_Release(d3d);
12706 DestroyWindow(window);
12709 static void texop_range_test(void)
12711 IDirect3DTexture9 *texture;
12712 D3DLOCKED_RECT locked_rect;
12713 IDirect3DDevice9 *device;
12714 IDirect3D9 *d3d;
12715 ULONG refcount;
12716 D3DCAPS9 caps;
12717 DWORD color;
12718 HWND window;
12719 HRESULT hr;
12721 static const struct
12723 float x, y, z;
12724 D3DCOLOR diffuse;
12726 quad[] =
12728 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
12729 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
12730 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
12731 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
12734 window = create_window();
12735 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12736 ok(!!d3d, "Failed to create a D3D object.\n");
12737 if (!(device = create_device(d3d, window, window, TRUE)))
12739 skip("Failed to create a D3D device, skipping tests.\n");
12740 goto done;
12743 /* We need ADD and SUBTRACT operations */
12744 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12745 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
12746 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD))
12748 skip("D3DTOP_ADD is not supported, skipping value range test.\n");
12749 IDirect3DDevice9_Release(device);
12750 goto done;
12752 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT))
12754 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test.\n");
12755 IDirect3DDevice9_Release(device);
12756 goto done;
12759 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12760 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
12761 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12762 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
12763 /* Stage 1: result = diffuse(=1.0) + diffuse
12764 * stage 2: result = result - tfactor(= 0.5)
12766 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12767 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12768 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
12769 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12770 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
12771 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12772 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
12773 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12774 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
12775 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12776 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12777 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12778 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
12779 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12781 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12782 ok(SUCCEEDED(hr), "Failed to clear device, hr %#x.\n\n", hr);
12783 hr = IDirect3DDevice9_BeginScene(device);
12784 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
12785 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12786 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
12787 hr = IDirect3DDevice9_EndScene(device);
12788 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
12790 color = getPixelColor(device, 320, 240);
12791 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
12792 color);
12793 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12794 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12796 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
12797 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
12798 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
12799 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
12800 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
12801 hr = IDirect3DTexture9_UnlockRect(texture, 0);
12802 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
12803 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
12804 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
12806 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
12807 * stage 2: result = result + diffuse(1.0)
12809 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12810 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12811 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12812 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12813 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12814 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12815 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
12816 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12817 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
12818 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12819 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
12820 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12821 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
12822 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12824 hr = IDirect3DDevice9_BeginScene(device);
12825 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
12826 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12827 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
12828 hr = IDirect3DDevice9_EndScene(device);
12829 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
12831 color = getPixelColor(device, 320, 240);
12832 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
12833 color);
12834 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12835 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12837 IDirect3DTexture9_Release(texture);
12838 refcount = IDirect3DDevice9_Release(device);
12839 ok(!refcount, "Device has %u references left.\n", refcount);
12840 done:
12841 IDirect3D9_Release(d3d);
12842 DestroyWindow(window);
12845 static void alphareplicate_test(void)
12847 IDirect3DDevice9 *device;
12848 IDirect3D9 *d3d;
12849 ULONG refcount;
12850 DWORD color;
12851 HWND window;
12852 HRESULT hr;
12854 static const struct
12856 struct vec3 position;
12857 DWORD diffuse;
12859 quad[] =
12861 {{-1.0f, -1.0f, 0.1f}, 0x80ff00ff},
12862 {{-1.0f, 1.0f, 0.1f}, 0x80ff00ff},
12863 {{ 1.0f, -1.0f, 0.1f}, 0x80ff00ff},
12864 {{ 1.0f, 1.0f, 0.1f}, 0x80ff00ff},
12867 window = create_window();
12868 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12869 ok(!!d3d, "Failed to create a D3D object.\n");
12870 if (!(device = create_device(d3d, window, window, TRUE)))
12872 skip("Failed to create a D3D device, skipping tests.\n");
12873 goto done;
12876 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12877 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12879 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12880 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12882 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12883 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12884 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
12885 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12887 hr = IDirect3DDevice9_BeginScene(device);
12888 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12889 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12890 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12891 hr = IDirect3DDevice9_EndScene(device);
12892 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12894 color = getPixelColor(device, 320, 240);
12895 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
12896 color);
12897 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12898 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12900 refcount = IDirect3DDevice9_Release(device);
12901 ok(!refcount, "Device has %u references left.\n", refcount);
12902 done:
12903 IDirect3D9_Release(d3d);
12904 DestroyWindow(window);
12907 static void dp3_alpha_test(void)
12909 IDirect3DDevice9 *device;
12910 IDirect3D9 *d3d;
12911 ULONG refcount;
12912 D3DCAPS9 caps;
12913 DWORD color;
12914 HWND window;
12915 HRESULT hr;
12917 static const struct
12919 struct vec3 position;
12920 DWORD diffuse;
12922 quad[] =
12924 {{-1.0f, -1.0f, 0.1f}, 0x408080c0},
12925 {{-1.0f, 1.0f, 0.1f}, 0x408080c0},
12926 {{ 1.0f, -1.0f, 0.1f}, 0x408080c0},
12927 {{ 1.0f, 1.0f, 0.1f}, 0x408080c0},
12930 window = create_window();
12931 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12932 ok(!!d3d, "Failed to create a D3D object.\n");
12933 if (!(device = create_device(d3d, window, window, TRUE)))
12935 skip("Failed to create a D3D device, skipping tests.\n");
12936 goto done;
12939 memset(&caps, 0, sizeof(caps));
12940 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12941 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
12942 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3))
12944 skip("D3DTOP_DOTPRODUCT3 not supported\n");
12945 IDirect3DDevice9_Release(device);
12946 goto done;
12949 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12950 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12952 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12953 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12955 /* dp3_x4 r0, diffuse_bias, tfactor_bias
12956 * mov r0.a, diffuse.a
12957 * mov r0, r0.a
12959 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
12960 * 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
12961 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
12963 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
12964 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12965 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
12966 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12967 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12968 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12969 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
12970 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12971 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
12972 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12973 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12974 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12975 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
12976 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12977 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
12978 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12979 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
12980 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12981 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12982 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
12984 hr = IDirect3DDevice9_BeginScene(device);
12985 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12986 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12987 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12988 hr = IDirect3DDevice9_EndScene(device);
12989 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12991 color = getPixelColor(device, 320, 240);
12992 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
12993 color);
12994 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12995 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12997 refcount = IDirect3DDevice9_Release(device);
12998 ok(!refcount, "Device has %u references left.\n", refcount);
12999 done:
13000 IDirect3D9_Release(d3d);
13001 DestroyWindow(window);
13004 static void zwriteenable_test(void)
13006 IDirect3DDevice9 *device;
13007 IDirect3D9 *d3d;
13008 D3DCOLOR color;
13009 ULONG refcount;
13010 HWND window;
13011 HRESULT hr;
13013 static const struct
13015 struct vec3 position;
13016 DWORD diffuse;
13018 quad1[] =
13020 {{-1.0f, -1.0f, 0.1f}, 0x00ff0000},
13021 {{-1.0f, 1.0f, 0.1f}, 0x00ff0000},
13022 {{ 1.0f, -1.0f, 0.1f}, 0x00ff0000},
13023 {{ 1.0f, 1.0f, 0.1f}, 0x00ff0000},
13025 quad2[] =
13027 {{-1.0f, -1.0f, 0.9f}, 0x0000ff00},
13028 {{-1.0f, 1.0f, 0.9f}, 0x0000ff00},
13029 {{ 1.0f, -1.0f, 0.9f}, 0x0000ff00},
13030 {{ 1.0f, 1.0f, 0.9f}, 0x0000ff00},
13033 window = create_window();
13034 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13035 ok(!!d3d, "Failed to create a D3D object.\n");
13036 if (!(device = create_device(d3d, window, window, TRUE)))
13038 skip("Failed to create a D3D device, skipping tests.\n");
13039 goto done;
13042 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
13043 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
13045 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13046 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
13047 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
13048 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
13049 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13050 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
13051 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13052 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
13053 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13054 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
13056 hr = IDirect3DDevice9_BeginScene(device);
13057 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13058 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1,
13059 * zenable = D3DZB_FALSE, zwriteenable = TRUE. The red color is written
13060 * because the z test is disabled. The question is whether the z = 0.1
13061 * values are written into the Z buffer. After the draw, set
13062 * zenable = TRUE and draw a green quad at z = 0.9. If the values are
13063 * written, the z test will fail(0.9 > 0.1) and the red color remains. If
13064 * the values are not written, the z test succeeds(0.9 < 1.0) and the
13065 * green color is written. It turns out that the screen is green, so
13066 * zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z
13067 * buffer. */
13068 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13069 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13070 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13071 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
13072 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13073 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13074 hr = IDirect3DDevice9_EndScene(device);
13075 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13077 color = getPixelColor(device, 320, 240);
13078 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
13079 color);
13080 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13081 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
13083 refcount = IDirect3DDevice9_Release(device);
13084 ok(!refcount, "Device has %u references left.\n", refcount);
13085 done:
13086 IDirect3D9_Release(d3d);
13087 DestroyWindow(window);
13090 static void alphatest_test(void)
13092 #define ALPHATEST_PASSED 0x0000ff00
13093 #define ALPHATEST_FAILED 0x00ff0000
13094 IDirect3DDevice9 *device;
13095 unsigned int i, j;
13096 IDirect3D9 *d3d;
13097 D3DCOLOR color;
13098 ULONG refcount;
13099 D3DCAPS9 caps;
13100 HWND window;
13101 HRESULT hr;
13103 static const struct
13105 D3DCMPFUNC func;
13106 D3DCOLOR color_less;
13107 D3DCOLOR color_equal;
13108 D3DCOLOR color_greater;
13110 testdata[] =
13112 {D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED},
13113 {D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED},
13114 {D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED},
13115 {D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED},
13116 {D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED},
13117 {D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED},
13118 {D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED},
13119 {D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED},
13121 static const struct
13123 struct vec3 position;
13124 DWORD diffuse;
13126 quad[] =
13128 {{-1.0f, -1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
13129 {{-1.0f, 1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
13130 {{ 1.0f, -1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
13131 {{ 1.0f, 1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
13134 window = create_window();
13135 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13136 ok(!!d3d, "Failed to create a D3D object.\n");
13137 if (!(device = create_device(d3d, window, window, TRUE)))
13139 skip("Failed to create a D3D device, skipping tests.\n");
13140 goto done;
13143 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
13144 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
13146 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13147 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
13148 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
13149 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
13150 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13151 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
13153 for (j = 0; j < 2; ++j)
13155 if (j == 1)
13157 /* Try a pixel shader instead of fixed function. The wined3d code
13158 * may emulate the alpha test either for performance reasons
13159 * (floating point RTs) or to work around driver bugs (GeForce
13160 * 7x00 cards on MacOS). There may be a different codepath for ffp
13161 * and shader in this case, and the test should cover both. */
13162 IDirect3DPixelShader9 *ps;
13163 static const DWORD shader_code[] =
13165 0xffff0101, /* ps_1_1 */
13166 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
13167 0x0000ffff /* end */
13169 memset(&caps, 0, sizeof(caps));
13170 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13171 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
13172 if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
13173 break;
13176 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
13177 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
13178 hr = IDirect3DDevice9_SetPixelShader(device, ps);
13179 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
13180 IDirect3DPixelShader9_Release(ps);
13183 for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
13184 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
13185 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
13187 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
13188 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
13189 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
13190 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
13191 hr = IDirect3DDevice9_BeginScene(device);
13192 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13193 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13194 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13195 hr = IDirect3DDevice9_EndScene(device);
13196 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13197 color = getPixelColor(device, 320, 240);
13198 ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
13199 color, testdata[i].color_less, testdata[i].func);
13200 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13201 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
13203 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
13204 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
13205 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
13206 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
13207 hr = IDirect3DDevice9_BeginScene(device);
13208 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13209 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13210 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13211 hr = IDirect3DDevice9_EndScene(device);
13212 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13213 color = getPixelColor(device, 320, 240);
13214 ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
13215 color, testdata[i].color_equal, testdata[i].func);
13216 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13217 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
13219 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
13220 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
13221 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
13222 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
13223 hr = IDirect3DDevice9_BeginScene(device);
13224 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13225 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13226 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13227 hr = IDirect3DDevice9_EndScene(device);
13228 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13229 color = getPixelColor(device, 320, 240);
13230 ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
13231 color, testdata[i].color_greater, testdata[i].func);
13232 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13233 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
13237 refcount = IDirect3DDevice9_Release(device);
13238 ok(!refcount, "Device has %u references left.\n", refcount);
13239 done:
13240 IDirect3D9_Release(d3d);
13241 DestroyWindow(window);
13244 static void sincos_test(void)
13246 IDirect3DVertexShader9 *sin_shader, *cos_shader;
13247 IDirect3DDevice9 *device;
13248 struct vec3 data[1280];
13249 IDirect3D9 *d3d;
13250 unsigned int i;
13251 ULONG refcount;
13252 D3DCAPS9 caps;
13253 HWND window;
13254 HRESULT hr;
13256 static const DWORD sin_shader_code[] =
13258 0xfffe0200, /* vs_2_0 */
13259 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
13260 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
13261 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
13262 0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.y, r1.x, c0, c1 */
13263 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
13264 0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002, /* mul oPos.y, r0.y, c2.w */
13265 0x02000001, 0xd00f0000, 0xa0a60002, /* mov oD0, c2.zyzz */
13266 0x0000ffff /* end */
13268 static const DWORD cos_shader_code[] =
13270 0xfffe0200, /* vs_2_0 */
13271 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
13272 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
13273 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
13274 0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.x, r1.x, c0, c1 */
13275 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
13276 0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002, /* mul oPos.y, r0.x, c2.w */
13277 0x02000001, 0xd00f0000, 0xa0a90002, /* mov oD0, c2.yzzz */
13278 0x0000ffff /* end */
13280 static const float sincosc1[4] = {D3DSINCOSCONST1};
13281 static const float sincosc2[4] = {D3DSINCOSCONST2};
13283 window = create_window();
13284 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13285 ok(!!d3d, "Failed to create a D3D object.\n");
13286 if (!(device = create_device(d3d, window, window, TRUE)))
13288 skip("Failed to create a D3D device, skipping tests.\n");
13289 goto done;
13292 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13293 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13294 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
13296 skip("No vs_2_0 support, skipping tests.\n");
13297 IDirect3DDevice9_Release(device);
13298 goto done;
13301 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
13302 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
13304 hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
13305 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
13306 hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
13307 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
13308 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13309 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
13310 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
13311 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
13312 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
13313 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
13315 /* Generate a point from -1 to 1 every 0.5 pixels */
13316 for(i = 0; i < 1280; i++) {
13317 data[i].x = (-640.0 + i) / 640.0;
13318 data[i].y = 0.0;
13319 data[i].z = 0.1;
13322 hr = IDirect3DDevice9_BeginScene(device);
13323 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13325 hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
13326 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
13327 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
13328 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13330 hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
13331 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
13332 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
13333 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13335 hr = IDirect3DDevice9_EndScene(device);
13336 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13338 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13339 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
13340 /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
13342 IDirect3DVertexShader9_Release(sin_shader);
13343 IDirect3DVertexShader9_Release(cos_shader);
13344 refcount = IDirect3DDevice9_Release(device);
13345 ok(!refcount, "Device has %u references left.\n", refcount);
13346 done:
13347 IDirect3D9_Release(d3d);
13348 DestroyWindow(window);
13351 static void loop_index_test(void)
13353 IDirect3DVertexShader9 *shader;
13354 IDirect3DDevice9 *device;
13355 IDirect3D9 *d3d;
13356 float values[4];
13357 ULONG refcount;
13358 D3DCAPS9 caps;
13359 DWORD color;
13360 HWND window;
13361 HRESULT hr;
13363 static const DWORD shader_code[] =
13365 0xfffe0200, /* vs_2_0 */
13366 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
13367 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
13368 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
13369 0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1] */
13370 0x0000001d, /* endloop */
13371 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
13372 0x02000001, 0xd00f0000, 0x80e40000, /* mov oD0, r0 */
13373 0x0000ffff /* END */
13375 static const float quad[] =
13377 -1.0f, -1.0f, 0.1f,
13378 -1.0f, 1.0f, 0.1f,
13379 1.0f, -1.0f, 0.1f,
13380 1.0f, 1.0f, 0.1f,
13382 static const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
13383 static const float one[4] = {1.0f, 1.0f, 1.0f, 1.0f};
13384 static const int i0[4] = {2, 10, -3, 0};
13386 window = create_window();
13387 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13388 ok(!!d3d, "Failed to create a D3D object.\n");
13389 if (!(device = create_device(d3d, window, window, TRUE)))
13391 skip("Failed to create a D3D device, skipping tests.\n");
13392 goto done;
13395 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13396 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13397 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
13399 skip("No vs_2_0 support, skipping tests.\n");
13400 IDirect3DDevice9_Release(device);
13401 goto done;
13404 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
13405 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
13406 hr = IDirect3DDevice9_SetVertexShader(device, shader);
13407 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
13408 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13409 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
13410 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
13411 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
13413 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
13414 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13415 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
13416 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13417 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
13418 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13419 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
13420 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13421 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
13422 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13423 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
13424 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13425 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
13426 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13427 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
13428 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13429 values[0] = 1.0;
13430 values[1] = 1.0;
13431 values[2] = 0.0;
13432 values[3] = 0.0;
13433 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
13434 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13435 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
13436 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13437 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
13438 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13439 values[0] = -1.0;
13440 values[1] = 0.0;
13441 values[2] = 0.0;
13442 values[3] = 0.0;
13443 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
13444 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13445 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
13446 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13447 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
13448 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13449 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
13450 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13451 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
13452 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13454 hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
13455 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
13457 hr = IDirect3DDevice9_BeginScene(device);
13458 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13459 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
13460 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13461 hr = IDirect3DDevice9_EndScene(device);
13462 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13463 color = getPixelColor(device, 320, 240);
13464 ok(color_match(color, 0x0000ff00, 1),
13465 "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
13466 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13467 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
13469 IDirect3DVertexShader9_Release(shader);
13470 refcount = IDirect3DDevice9_Release(device);
13471 ok(!refcount, "Device has %u references left.\n", refcount);
13472 done:
13473 IDirect3D9_Release(d3d);
13474 DestroyWindow(window);
13477 static void sgn_test(void)
13479 IDirect3DVertexShader9 *shader;
13480 IDirect3DDevice9 *device;
13481 IDirect3D9 *d3d;
13482 ULONG refcount;
13483 D3DCAPS9 caps;
13484 DWORD color;
13485 HWND window;
13486 HRESULT hr;
13488 static const DWORD shader_code[] =
13490 0xfffe0200, /* vs_2_0 */
13491 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position o0 */
13492 0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
13493 0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0 */
13494 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
13495 0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002, /* sgn r0, c0, r1, r2 */
13496 0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001, /* add oD0, r0, c1 */
13497 0x0000ffff /* end */
13499 static const float quad[] =
13501 -1.0f, -1.0f, 0.1f,
13502 -1.0f, 1.0f, 0.1f,
13503 1.0f, -1.0f, 0.1f,
13504 1.0f, 1.0f, 0.1f,
13507 window = create_window();
13508 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13509 ok(!!d3d, "Failed to create a D3D object.\n");
13510 if (!(device = create_device(d3d, window, window, TRUE)))
13512 skip("Failed to create a D3D device, skipping tests.\n");
13513 goto done;
13516 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13517 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13518 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
13520 skip("No vs_2_0 support, skipping tests.\n");
13521 IDirect3DDevice9_Release(device);
13522 goto done;
13525 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
13526 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
13527 hr = IDirect3DDevice9_SetVertexShader(device, shader);
13528 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
13529 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13530 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
13531 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
13532 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
13534 hr = IDirect3DDevice9_BeginScene(device);
13535 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13536 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
13537 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13538 hr = IDirect3DDevice9_EndScene(device);
13539 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13540 color = getPixelColor(device, 320, 240);
13541 ok(color_match(color, 0x008000ff, 1),
13542 "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
13543 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13544 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
13546 IDirect3DVertexShader9_Release(shader);
13547 refcount = IDirect3DDevice9_Release(device);
13548 ok(!refcount, "Device has %u references left.\n", refcount);
13549 done:
13550 IDirect3D9_Release(d3d);
13551 DestroyWindow(window);
13554 static void viewport_test(void)
13556 IDirect3DDevice9 *device;
13557 BOOL draw_failed = TRUE;
13558 D3DVIEWPORT9 vp;
13559 IDirect3D9 *d3d;
13560 ULONG refcount;
13561 DWORD color;
13562 HWND window;
13563 HRESULT hr;
13565 static const float quad[] =
13567 -0.5f, -0.5f, 0.1f,
13568 -0.5f, 0.5f, 0.1f,
13569 0.5f, -0.5f, 0.1f,
13570 0.5f, 0.5f, 0.1f,
13573 window = create_window();
13574 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13575 ok(!!d3d, "Failed to create a D3D object.\n");
13576 if (!(device = create_device(d3d, window, window, TRUE)))
13578 skip("Failed to create a D3D device, skipping tests.\n");
13579 goto done;
13582 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
13583 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
13585 /* Test a viewport with Width and Height bigger than the surface dimensions
13587 * TODO: Test Width < surface.width, but X + Width > surface.width
13588 * TODO: Test Width < surface.width, what happens with the height?
13590 * The expected behavior is that the viewport behaves like the "default"
13591 * viewport with X = Y = 0, Width = surface_width, Height = surface_height,
13592 * MinZ = 0.0, MaxZ = 1.0.
13594 * Starting with Windows 7 the behavior among driver versions is not
13595 * consistent. The SetViewport call is accepted on all drivers. Some
13596 * drivers(older nvidia ones) refuse to draw and return an error. Newer
13597 * nvidia drivers draw, but use the actual values in the viewport and only
13598 * display the upper left part on the surface.
13600 memset(&vp, 0, sizeof(vp));
13601 vp.X = 0;
13602 vp.Y = 0;
13603 vp.Width = 10000;
13604 vp.Height = 10000;
13605 vp.MinZ = 0.0;
13606 vp.MaxZ = 0.0;
13607 hr = IDirect3DDevice9_SetViewport(device, &vp);
13608 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
13610 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13611 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
13613 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13614 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
13615 hr = IDirect3DDevice9_BeginScene(device);
13616 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13617 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
13618 ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
13619 draw_failed = FAILED(hr);
13620 hr = IDirect3DDevice9_EndScene(device);
13621 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13623 if(!draw_failed)
13625 color = getPixelColor(device, 158, 118);
13626 ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
13627 color = getPixelColor(device, 162, 118);
13628 ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
13629 color = getPixelColor(device, 158, 122);
13630 ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
13631 color = getPixelColor(device, 162, 122);
13632 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (162,122) has color %08x\n", color);
13634 color = getPixelColor(device, 478, 358);
13635 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (478,358 has color %08x\n", color);
13636 color = getPixelColor(device, 482, 358);
13637 ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
13638 color = getPixelColor(device, 478, 362);
13639 ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
13640 color = getPixelColor(device, 482, 362);
13641 ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
13644 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13645 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
13647 refcount = IDirect3DDevice9_Release(device);
13648 ok(!refcount, "Device has %u references left.\n", refcount);
13649 done:
13650 IDirect3D9_Release(d3d);
13651 DestroyWindow(window);
13654 /* This test tests depth clamping / clipping behaviour:
13655 * - With software vertex processing, depth values are clamped to the
13656 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
13657 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
13658 * same as regular vertices here.
13659 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
13660 * Normal vertices are always clipped. Pretransformed vertices are
13661 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
13662 * - The viewport's MinZ/MaxZ is irrelevant for this.
13664 static void depth_clamp_test(void)
13666 IDirect3DDevice9 *device;
13667 D3DVIEWPORT9 vp;
13668 IDirect3D9 *d3d;
13669 D3DCOLOR color;
13670 ULONG refcount;
13671 D3DCAPS9 caps;
13672 HWND window;
13673 HRESULT hr;
13675 static const struct
13677 struct vec4 position;
13678 DWORD diffuse;
13680 quad1[] =
13682 {{ 0.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
13683 {{640.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
13684 {{ 0.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
13685 {{640.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
13687 quad2[] =
13689 {{ 0.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
13690 {{640.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
13691 {{ 0.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
13692 {{640.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
13694 quad3[] =
13696 {{112.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
13697 {{208.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
13698 {{112.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
13699 {{208.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
13701 quad4[] =
13703 {{ 42.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
13704 {{112.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
13705 {{ 42.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
13706 {{112.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
13708 static const struct
13710 struct vec3 position;
13711 DWORD diffuse;
13713 quad5[] =
13715 {{-0.5f, 0.5f, 10.0f}, 0xff14f914},
13716 {{ 0.5f, 0.5f, 10.0f}, 0xff14f914},
13717 {{-0.5f, -0.5f, 10.0f}, 0xff14f914},
13718 {{ 0.5f, -0.5f, 10.0f}, 0xff14f914},
13720 quad6[] =
13722 {{-1.0f, 0.5f, 10.0f}, 0xfff91414},
13723 {{ 1.0f, 0.5f, 10.0f}, 0xfff91414},
13724 {{-1.0f, 0.25f, 10.0f}, 0xfff91414},
13725 {{ 1.0f, 0.25f, 10.0f}, 0xfff91414},
13728 window = create_window();
13729 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13730 ok(!!d3d, "Failed to create a D3D object.\n");
13731 if (!(device = create_device(d3d, window, window, TRUE)))
13733 skip("Failed to create a D3D device, skipping tests.\n");
13734 goto done;
13737 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13738 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13740 vp.X = 0;
13741 vp.Y = 0;
13742 vp.Width = 640;
13743 vp.Height = 480;
13744 vp.MinZ = 0.0;
13745 vp.MaxZ = 7.5;
13747 hr = IDirect3DDevice9_SetViewport(device, &vp);
13748 if(FAILED(hr))
13750 /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
13751 * the tests because the 7.5 is just intended to show that it doesn't have
13752 * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
13753 * viewport and continue.
13755 ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
13756 vp.MaxZ = 1.0;
13757 hr = IDirect3DDevice9_SetViewport(device, &vp);
13759 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
13761 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
13762 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13764 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
13765 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13766 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13767 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13768 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13769 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13770 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13771 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13773 hr = IDirect3DDevice9_BeginScene(device);
13774 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13776 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
13777 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13779 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13780 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13781 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13782 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13784 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
13785 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13787 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
13788 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13789 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
13790 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13792 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
13793 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13795 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13796 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13798 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
13799 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13801 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
13802 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13804 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
13805 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13807 hr = IDirect3DDevice9_EndScene(device);
13808 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13810 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
13812 color = getPixelColor(device, 75, 75);
13813 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13814 color = getPixelColor(device, 150, 150);
13815 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13816 color = getPixelColor(device, 320, 240);
13817 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13818 color = getPixelColor(device, 320, 330);
13819 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13820 color = getPixelColor(device, 320, 330);
13821 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13823 else
13825 color = getPixelColor(device, 75, 75);
13826 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
13827 color = getPixelColor(device, 150, 150);
13828 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
13829 color = getPixelColor(device, 320, 240);
13830 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
13831 color = getPixelColor(device, 320, 330);
13832 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13833 color = getPixelColor(device, 320, 330);
13834 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13837 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13838 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13840 refcount = IDirect3DDevice9_Release(device);
13841 ok(!refcount, "Device has %u references left.\n", refcount);
13842 done:
13843 IDirect3D9_Release(d3d);
13844 DestroyWindow(window);
13847 static void depth_bounds_test(void)
13849 static const struct
13851 struct vec4 position;
13852 DWORD diffuse;
13854 quad1[] =
13856 {{ 0.0f, 0.0f, 0.0f, 1.0f}, 0xfff9e814},
13857 {{640.0f, 0.0f, 0.0f, 1.0f}, 0xfff9e814},
13858 {{ 0.0f, 480.0f, 1.0f, 1.0f}, 0xfff9e814},
13859 {{640.0f, 480.0f, 1.0f, 1.0f}, 0xfff9e814},
13861 quad2[] =
13863 {{ 0.0f, 0.0f, 0.6f, 1.0f}, 0xff002b7f},
13864 {{640.0f, 0.0f, 0.6f, 1.0f}, 0xff002b7f},
13865 {{ 0.0f, 480.0f, 0.6f, 1.0f}, 0xff002b7f},
13866 {{640.0f, 480.0f, 0.6f, 1.0f}, 0xff002b7f},
13868 quad3[] =
13870 {{ 0.0f, 100.0f, 0.6f, 1.0f}, 0xfff91414},
13871 {{640.0f, 100.0f, 0.6f, 1.0f}, 0xfff91414},
13872 {{ 0.0f, 160.0f, 0.6f, 1.0f}, 0xfff91414},
13873 {{640.0f, 160.0f, 0.6f, 1.0f}, 0xfff91414},
13876 union {
13877 DWORD d;
13878 float f;
13879 } tmpvalue;
13881 IDirect3DSurface9 *offscreen_surface = NULL;
13882 IDirect3DDevice9 *device;
13883 IDirect3D9 *d3d;
13884 D3DCOLOR color;
13885 ULONG refcount;
13886 HWND window;
13887 HRESULT hr;
13889 window = create_window();
13890 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13891 ok(!!d3d, "Failed to create a D3D object.\n");
13892 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
13893 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK)
13895 skip("No NVDB (depth bounds test) support, skipping tests.\n");
13896 goto done;
13898 if (!(device = create_device(d3d, window, window, TRUE)))
13900 skip("Failed to create a D3D device, skipping tests.\n");
13901 goto done;
13904 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
13905 MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
13906 ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
13907 if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
13909 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
13910 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13912 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13913 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13914 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13915 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13916 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13917 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13918 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13919 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13922 hr = IDirect3DDevice9_BeginScene(device);
13923 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13925 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
13926 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13928 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13929 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13931 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
13932 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13934 tmpvalue.f = 0.625;
13935 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
13936 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13938 tmpvalue.f = 0.75;
13939 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
13940 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13942 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13943 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13945 tmpvalue.f = 0.75;
13946 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
13947 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13949 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
13950 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13952 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
13953 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13955 hr = IDirect3DDevice9_EndScene(device);
13956 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13958 color = getPixelColor(device, 150, 130);
13959 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13960 color = getPixelColor(device, 150, 200);
13961 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13962 color = getPixelColor(device, 150, 300-5);
13963 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13964 color = getPixelColor(device, 150, 300+5);
13965 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
13966 color = getPixelColor(device, 150, 330);
13967 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
13968 color = getPixelColor(device, 150, 360-5);
13969 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
13970 color = getPixelColor(device, 150, 360+5);
13971 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13973 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13974 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13975 refcount = IDirect3DDevice9_Release(device);
13976 ok(!refcount, "Device has %u references left.\n", refcount);
13977 done:
13978 IDirect3D9_Release(d3d);
13979 DestroyWindow(window);
13982 static void depth_buffer_test(void)
13984 static const struct
13986 struct vec3 position;
13987 DWORD diffuse;
13989 quad1[] =
13991 {{-1.0, 1.0, 0.33f}, 0xff00ff00},
13992 {{ 1.0, 1.0, 0.33f}, 0xff00ff00},
13993 {{-1.0, -1.0, 0.33f}, 0xff00ff00},
13994 {{ 1.0, -1.0, 0.33f}, 0xff00ff00},
13996 quad2[] =
13998 {{-1.0, 1.0, 0.50f}, 0xffff00ff},
13999 {{ 1.0, 1.0, 0.50f}, 0xffff00ff},
14000 {{-1.0, -1.0, 0.50f}, 0xffff00ff},
14001 {{ 1.0, -1.0, 0.50f}, 0xffff00ff},
14003 quad3[] =
14005 {{-1.0, 1.0, 0.66f}, 0xffff0000},
14006 {{ 1.0, 1.0, 0.66f}, 0xffff0000},
14007 {{-1.0, -1.0, 0.66f}, 0xffff0000},
14008 {{ 1.0, -1.0, 0.66f}, 0xffff0000},
14010 static const DWORD expected_colors[4][4] =
14012 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
14013 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
14014 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
14015 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
14018 IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
14019 IDirect3DDevice9 *device;
14020 unsigned int i, j;
14021 D3DVIEWPORT9 vp;
14022 IDirect3D9 *d3d;
14023 D3DCOLOR color;
14024 ULONG refcount;
14025 HWND window;
14026 HRESULT hr;
14028 window = create_window();
14029 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14030 ok(!!d3d, "Failed to create a D3D object.\n");
14031 if (!(device = create_device(d3d, window, window, TRUE)))
14033 skip("Failed to create a D3D device, skipping tests.\n");
14034 goto done;
14037 vp.X = 0;
14038 vp.Y = 0;
14039 vp.Width = 640;
14040 vp.Height = 480;
14041 vp.MinZ = 0.0;
14042 vp.MaxZ = 1.0;
14044 hr = IDirect3DDevice9_SetViewport(device, &vp);
14045 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
14047 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14048 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14049 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14050 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14051 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14052 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14053 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
14054 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14055 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
14056 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14058 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
14059 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14060 hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
14061 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
14062 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
14063 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
14064 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
14065 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
14066 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
14067 D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
14068 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
14070 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
14071 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14072 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
14073 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14075 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
14076 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14077 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
14078 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14080 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
14081 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14082 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
14083 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14085 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
14086 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14087 hr = IDirect3DDevice9_BeginScene(device);
14088 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14089 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
14090 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14091 hr = IDirect3DDevice9_EndScene(device);
14092 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14094 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
14095 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14097 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
14098 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14100 hr = IDirect3DDevice9_BeginScene(device);
14101 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14102 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
14103 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14104 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
14105 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14106 hr = IDirect3DDevice9_EndScene(device);
14107 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14109 for (i = 0; i < 4; ++i)
14111 for (j = 0; j < 4; ++j)
14113 unsigned int x = 80 * ((2 * j) + 1);
14114 unsigned int y = 60 * ((2 * i) + 1);
14115 color = getPixelColor(device, x, y);
14116 ok(color_match(color, expected_colors[i][j], 0),
14117 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
14121 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14122 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14124 IDirect3DSurface9_Release(backbuffer);
14125 IDirect3DSurface9_Release(rt3);
14126 IDirect3DSurface9_Release(rt2);
14127 IDirect3DSurface9_Release(rt1);
14128 refcount = IDirect3DDevice9_Release(device);
14129 ok(!refcount, "Device has %u references left.\n", refcount);
14130 done:
14131 IDirect3D9_Release(d3d);
14132 DestroyWindow(window);
14135 /* Test that partial depth copies work the way they're supposed to. The clear
14136 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
14137 * the following draw should only copy back the part that was modified. */
14138 static void depth_buffer2_test(void)
14140 static const struct
14142 struct vec3 position;
14143 DWORD diffuse;
14145 quad[] =
14147 {{-1.0f, 1.0f, 0.66f}, 0xffff0000},
14148 {{ 1.0f, 1.0f, 0.66f}, 0xffff0000},
14149 {{-1.0f, -1.0f, 0.66f}, 0xffff0000},
14150 {{ 1.0f, -1.0f, 0.66f}, 0xffff0000},
14153 IDirect3DSurface9 *backbuffer, *rt1, *rt2;
14154 IDirect3DDevice9 *device;
14155 unsigned int i, j;
14156 D3DVIEWPORT9 vp;
14157 IDirect3D9 *d3d;
14158 D3DCOLOR color;
14159 ULONG refcount;
14160 HWND window;
14161 HRESULT hr;
14163 window = create_window();
14164 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14165 ok(!!d3d, "Failed to create a D3D object.\n");
14166 if (!(device = create_device(d3d, window, window, TRUE)))
14168 skip("Failed to create a D3D device, skipping tests.\n");
14169 goto done;
14172 vp.X = 0;
14173 vp.Y = 0;
14174 vp.Width = 640;
14175 vp.Height = 480;
14176 vp.MinZ = 0.0;
14177 vp.MaxZ = 1.0;
14179 hr = IDirect3DDevice9_SetViewport(device, &vp);
14180 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
14182 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14183 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14184 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14185 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14186 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14187 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14188 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
14189 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14190 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
14191 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14193 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
14194 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
14195 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
14196 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
14197 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
14198 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
14199 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
14200 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14202 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
14203 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14204 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
14205 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14207 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
14208 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14209 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
14210 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14212 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
14213 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14214 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
14215 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14217 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
14218 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14220 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
14221 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14223 hr = IDirect3DDevice9_BeginScene(device);
14224 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14225 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14226 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14227 hr = IDirect3DDevice9_EndScene(device);
14228 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14230 for (i = 0; i < 4; ++i)
14232 for (j = 0; j < 4; ++j)
14234 unsigned int x = 80 * ((2 * j) + 1);
14235 unsigned int y = 60 * ((2 * i) + 1);
14236 color = getPixelColor(device, x, y);
14237 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
14238 "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
14242 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14243 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14245 IDirect3DSurface9_Release(backbuffer);
14246 IDirect3DSurface9_Release(rt2);
14247 IDirect3DSurface9_Release(rt1);
14248 refcount = IDirect3DDevice9_Release(device);
14249 ok(!refcount, "Device has %u references left.\n", refcount);
14250 done:
14251 IDirect3D9_Release(d3d);
14252 DestroyWindow(window);
14255 static void depth_blit_test(void)
14257 static const struct
14259 struct vec3 position;
14260 DWORD diffuse;
14262 quad1[] =
14264 {{-1.0f, 1.0f, 0.33f}, 0xff00ff00},
14265 {{ 1.0f, 1.0f, 0.33f}, 0xff00ff00},
14266 {{-1.0f, -1.0f, 0.33f}, 0xff00ff00},
14267 {{ 1.0f, -1.0f, 0.33f}, 0xff00ff00},
14269 quad2[] =
14271 {{-1.0f, 1.0f, 0.66f}, 0xff0000ff},
14272 {{ 1.0f, 1.0f, 0.66f}, 0xff0000ff},
14273 {{-1.0f, -1.0f, 0.66f}, 0xff0000ff},
14274 {{ 1.0f, -1.0f, 0.66f}, 0xff0000ff},
14276 static const DWORD expected_colors[4][4] =
14278 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
14279 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
14280 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
14281 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
14284 IDirect3DSurface9 *backbuffer, *ds1, *ds2, *ds3;
14285 IDirect3DDevice9 *device;
14286 RECT src_rect, dst_rect;
14287 unsigned int i, j;
14288 D3DVIEWPORT9 vp;
14289 IDirect3D9 *d3d;
14290 D3DCOLOR color;
14291 ULONG refcount;
14292 HWND window;
14293 HRESULT hr;
14295 window = create_window();
14296 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14297 ok(!!d3d, "Failed to create a D3D object.\n");
14298 if (!(device = create_device(d3d, window, window, TRUE)))
14300 skip("Failed to create a D3D device, skipping tests.\n");
14301 goto done;
14304 vp.X = 0;
14305 vp.Y = 0;
14306 vp.Width = 640;
14307 vp.Height = 480;
14308 vp.MinZ = 0.0;
14309 vp.MaxZ = 1.0;
14311 hr = IDirect3DDevice9_SetViewport(device, &vp);
14312 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
14314 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
14315 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14316 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
14317 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
14318 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
14319 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
14320 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
14321 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14322 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 320, 240, D3DFMT_D24S8, 0, 0, FALSE, &ds3, NULL);
14323 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
14325 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14326 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14327 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14328 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14329 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
14330 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14331 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
14332 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14334 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14335 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14336 SetRect(&dst_rect, 0, 0, 480, 360);
14337 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
14338 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14339 SetRect(&dst_rect, 0, 0, 320, 240);
14340 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
14341 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14343 /* Partial blit. */
14344 SetRect(&src_rect, 0, 0, 320, 240);
14345 SetRect(&dst_rect, 0, 0, 320, 240);
14346 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
14347 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14348 /* Flipped. */
14349 SetRect(&src_rect, 0, 0, 640, 480);
14350 SetRect(&dst_rect, 0, 480, 640, 0);
14351 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
14352 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14353 /* Full, explicit. */
14354 SetRect(&src_rect, 0, 0, 640, 480);
14355 SetRect(&dst_rect, 0, 0, 640, 480);
14356 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
14357 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14358 /* Filtered blit. */
14359 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
14360 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14361 /* Depth -> color blit.*/
14362 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
14363 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14364 IDirect3DSurface9_Release(backbuffer);
14365 /* Full surface, different sizes */
14366 hr = IDirect3DDevice9_StretchRect(device, ds3, NULL, ds1, NULL, D3DTEXF_POINT);
14367 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14368 hr = IDirect3DDevice9_StretchRect(device, ds1, NULL, ds3, NULL, D3DTEXF_POINT);
14369 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14371 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
14372 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14373 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
14374 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14375 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
14376 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14378 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
14379 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14380 hr = IDirect3DDevice9_BeginScene(device);
14381 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14382 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
14383 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14384 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
14385 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14386 hr = IDirect3DDevice9_EndScene(device);
14387 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14389 for (i = 0; i < 4; ++i)
14391 for (j = 0; j < 4; ++j)
14393 unsigned int x = 80 * ((2 * j) + 1);
14394 unsigned int y = 60 * ((2 * i) + 1);
14395 color = getPixelColor(device, x, y);
14396 ok(color_match(color, expected_colors[i][j], 0),
14397 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
14401 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14402 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14404 IDirect3DSurface9_Release(ds3);
14405 IDirect3DSurface9_Release(ds2);
14406 IDirect3DSurface9_Release(ds1);
14407 refcount = IDirect3DDevice9_Release(device);
14408 ok(!refcount, "Device has %u references left.\n", refcount);
14409 done:
14410 IDirect3D9_Release(d3d);
14411 DestroyWindow(window);
14414 static void intz_test(void)
14416 static const DWORD ps_code[] =
14418 0xffff0200, /* ps_2_0 */
14419 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
14420 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
14421 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
14422 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
14423 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
14424 0x03010042, 0x800f0001, 0xb0e40000, 0xa0e40800, /* texldp r1, t0, s0 */
14425 0x02000001, 0x80020000, 0x80000001, /* mov r0.y, r1.x */
14426 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14427 0x0000ffff, /* end */
14429 struct
14431 float x, y, z;
14432 float s, t, p, q;
14434 quad[] =
14436 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
14437 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
14438 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
14439 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
14441 half_quad_1[] =
14443 { -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
14444 { 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
14445 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
14446 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
14448 half_quad_2[] =
14450 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
14451 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
14452 { -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
14453 { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
14455 struct
14457 UINT x, y;
14458 D3DCOLOR color;
14460 expected_colors[] =
14462 { 80, 100, 0x20204020},
14463 {240, 100, 0x6060bf60},
14464 {400, 100, 0x9f9f409f},
14465 {560, 100, 0xdfdfbfdf},
14466 { 80, 450, 0x20204020},
14467 {240, 450, 0x6060bf60},
14468 {400, 450, 0x9f9f409f},
14469 {560, 450, 0xdfdfbfdf},
14472 IDirect3DSurface9 *original_rt, *rt;
14473 struct surface_readback rb;
14474 IDirect3DTexture9 *texture;
14475 IDirect3DPixelShader9 *ps;
14476 IDirect3DDevice9 *device;
14477 IDirect3DSurface9 *ds;
14478 IDirect3D9 *d3d;
14479 ULONG refcount;
14480 D3DCAPS9 caps;
14481 HWND window;
14482 HRESULT hr;
14483 UINT i;
14485 window = create_window();
14486 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14487 ok(!!d3d, "Failed to create a D3D object.\n");
14488 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
14489 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
14491 skip("No INTZ support, skipping INTZ test.\n");
14492 goto done;
14494 if (!(device = create_device(d3d, window, window, TRUE)))
14496 skip("Failed to create a D3D device, skipping tests.\n");
14497 goto done;
14500 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14501 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
14502 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
14504 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
14505 IDirect3DDevice9_Release(device);
14506 goto done;
14508 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
14510 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
14511 IDirect3DDevice9_Release(device);
14512 goto done;
14515 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14516 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14518 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
14519 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
14520 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
14521 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
14522 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
14523 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
14524 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
14525 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
14527 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
14528 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14529 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14530 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14531 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
14532 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14533 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14534 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14535 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14536 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14538 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
14539 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14540 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
14541 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14542 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
14543 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14544 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
14545 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14546 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
14547 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14549 /* Render offscreen, using the INTZ texture as depth buffer */
14550 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14551 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14552 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14553 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14554 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14555 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14556 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14557 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14559 /* Setup the depth/stencil surface. */
14560 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14561 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14563 hr = IDirect3DDevice9_BeginScene(device);
14564 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14565 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14566 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14567 hr = IDirect3DDevice9_EndScene(device);
14568 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14570 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14571 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14572 IDirect3DSurface9_Release(ds);
14573 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14574 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14575 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14576 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14577 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14578 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14580 /* Read the depth values back. */
14581 hr = IDirect3DDevice9_BeginScene(device);
14582 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14583 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14584 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14585 hr = IDirect3DDevice9_EndScene(device);
14586 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14588 get_rt_readback(original_rt, &rb);
14589 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14591 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
14592 ok(color_match(color, expected_colors[i].color, 1),
14593 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14594 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14596 release_surface_readback(&rb);
14598 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14599 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14601 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14602 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14603 IDirect3DTexture9_Release(texture);
14605 /* Render onscreen while using the INTZ texture as depth buffer */
14606 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
14607 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
14608 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14609 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14610 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14611 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14612 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14613 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14615 /* Setup the depth/stencil surface. */
14616 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14617 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14619 hr = IDirect3DDevice9_BeginScene(device);
14620 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14621 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14622 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14623 hr = IDirect3DDevice9_EndScene(device);
14624 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14626 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14627 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14628 IDirect3DSurface9_Release(ds);
14629 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14630 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14631 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14632 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14634 /* Read the depth values back. */
14635 hr = IDirect3DDevice9_BeginScene(device);
14636 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14637 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14638 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14639 hr = IDirect3DDevice9_EndScene(device);
14640 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14642 get_rt_readback(original_rt, &rb);
14643 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14645 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
14646 ok(color_match(color, expected_colors[i].color, 1),
14647 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14648 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14650 release_surface_readback(&rb);
14652 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14653 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14655 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14656 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14657 IDirect3DTexture9_Release(texture);
14659 /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
14660 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
14661 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
14662 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14663 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14665 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14666 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14667 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14668 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14669 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14670 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14672 /* Setup the depth/stencil surface. */
14673 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14674 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14676 hr = IDirect3DDevice9_BeginScene(device);
14677 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14678 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
14679 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14680 hr = IDirect3DDevice9_EndScene(device);
14681 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14683 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14684 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14686 hr = IDirect3DDevice9_BeginScene(device);
14687 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14688 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
14689 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14690 hr = IDirect3DDevice9_EndScene(device);
14691 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14693 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14694 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14695 IDirect3DSurface9_Release(ds);
14696 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14697 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14698 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14699 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14701 /* Read the depth values back. */
14702 hr = IDirect3DDevice9_BeginScene(device);
14703 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14704 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14705 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14706 hr = IDirect3DDevice9_EndScene(device);
14707 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14709 get_rt_readback(original_rt, &rb);
14710 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14712 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
14713 ok(color_match(color, expected_colors[i].color, 1),
14714 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14715 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14717 release_surface_readback(&rb);
14719 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14720 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14722 IDirect3DTexture9_Release(texture);
14723 IDirect3DPixelShader9_Release(ps);
14724 IDirect3DSurface9_Release(original_rt);
14725 IDirect3DSurface9_Release(rt);
14726 refcount = IDirect3DDevice9_Release(device);
14727 ok(!refcount, "Device has %u references left.\n", refcount);
14728 done:
14729 IDirect3D9_Release(d3d);
14730 DestroyWindow(window);
14733 static void shadow_test(void)
14735 static const DWORD ps_code[] =
14737 0xffff0200, /* ps_2_0 */
14738 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
14739 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
14740 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
14741 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
14742 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
14743 0x03010042, 0x800f0001, 0xb0e40000, 0xa0e40800, /* texldp r1, t0, s0 */
14744 0x02000001, 0x80020000, 0x80000001, /* mov r0.y, r1.x */
14745 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14746 0x0000ffff, /* end */
14748 struct
14750 D3DFORMAT format;
14751 const char *name;
14753 formats[] =
14755 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
14756 {D3DFMT_D32, "D3DFMT_D32"},
14757 {D3DFMT_D15S1, "D3DFMT_D15S1"},
14758 {D3DFMT_D24S8, "D3DFMT_D24S8"},
14759 {D3DFMT_D24X8, "D3DFMT_D24X8"},
14760 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
14761 {D3DFMT_D16, "D3DFMT_D16"},
14762 {D3DFMT_D32F_LOCKABLE, "D3DFMT_D32F_LOCKABLE"},
14763 {D3DFMT_D24FS8, "D3DFMT_D24FS8"},
14765 struct
14767 float x, y, z;
14768 float s, t, p, q;
14770 quad[] =
14772 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
14773 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
14774 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
14775 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
14777 struct
14779 UINT x, y;
14780 D3DCOLOR color;
14782 expected_colors[] =
14784 {400, 60, 0x00000000},
14785 {560, 180, 0xffff00ff},
14786 {560, 300, 0xffff00ff},
14787 {400, 420, 0xffffffff},
14788 {240, 420, 0xffffffff},
14789 { 80, 300, 0x00000000},
14790 { 80, 180, 0x00000000},
14791 {240, 60, 0x00000000},
14794 IDirect3DSurface9 *original_ds, *original_rt, *rt;
14795 struct surface_readback rb;
14796 IDirect3DPixelShader9 *ps;
14797 IDirect3DDevice9 *device;
14798 IDirect3D9 *d3d;
14799 ULONG refcount;
14800 D3DCAPS9 caps;
14801 HWND window;
14802 HRESULT hr;
14803 UINT i;
14805 window = create_window();
14806 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14807 ok(!!d3d, "Failed to create a D3D object.\n");
14808 if (!(device = create_device(d3d, window, window, TRUE)))
14810 skip("Failed to create a D3D device, skipping tests.\n");
14811 goto done;
14814 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14815 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
14816 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
14818 skip("No pixel shader 2.0 support, skipping shadow test.\n");
14819 IDirect3DDevice9_Release(device);
14820 goto done;
14823 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14824 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14825 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
14826 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
14828 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
14829 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
14830 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
14831 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
14832 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
14834 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
14835 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14836 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14837 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14838 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
14839 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14840 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14841 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14842 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14843 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14845 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
14846 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14847 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
14848 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14849 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
14850 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14851 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
14852 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14853 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
14854 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14856 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
14858 D3DFORMAT format = formats[i].format;
14859 IDirect3DTexture9 *texture;
14860 IDirect3DSurface9 *ds;
14861 unsigned int j;
14863 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
14864 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format)))
14865 continue;
14867 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
14868 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
14869 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
14871 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14872 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14874 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14875 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14877 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14878 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14880 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14881 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14883 /* Setup the depth/stencil surface. */
14884 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14885 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14887 hr = IDirect3DDevice9_BeginScene(device);
14888 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14889 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14890 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14891 hr = IDirect3DDevice9_EndScene(device);
14892 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14894 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14895 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14896 IDirect3DSurface9_Release(ds);
14898 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14899 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14901 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14902 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14904 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14905 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14907 /* Do the actual shadow mapping. */
14908 hr = IDirect3DDevice9_BeginScene(device);
14909 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14910 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14911 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14912 hr = IDirect3DDevice9_EndScene(device);
14913 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14915 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14916 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14917 IDirect3DTexture9_Release(texture);
14919 get_rt_readback(original_rt, &rb);
14920 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
14922 D3DCOLOR color = get_readback_color(&rb, expected_colors[j].x, expected_colors[j].y);
14923 /* Geforce 7 on Windows returns 1.0 in alpha when the depth format is D24S8 or D24X8,
14924 * whereas other GPUs (all AMD, newer Nvidia) return the same value they return in .rgb.
14925 * Accept alpha mismatches as broken but make sure to check the color channels. */
14926 ok(color_match(color, expected_colors[j].color, 0)
14927 || broken(color_match(color & 0x00ffffff, expected_colors[j].color & 0x00ffffff, 0)),
14928 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
14929 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
14930 formats[i].name, color);
14932 release_surface_readback(&rb);
14934 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14935 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14938 IDirect3DPixelShader9_Release(ps);
14939 IDirect3DSurface9_Release(original_ds);
14940 IDirect3DSurface9_Release(original_rt);
14941 IDirect3DSurface9_Release(rt);
14942 refcount = IDirect3DDevice9_Release(device);
14943 ok(!refcount, "Device has %u references left.\n", refcount);
14944 done:
14945 IDirect3D9_Release(d3d);
14946 DestroyWindow(window);
14949 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
14951 static const struct
14953 struct vec3 position;
14954 DWORD diffuse;
14956 quad1[] =
14958 {{-1.0f, -1.0f, 0.0f}, 0xfff9e814},
14959 {{-1.0f, 1.0f, 0.0f}, 0xfff9e814},
14960 {{ 1.0f, -1.0f, 0.0f}, 0xfff9e814},
14961 {{ 1.0f, 1.0f, 0.0f}, 0xfff9e814},
14963 quad2[] =
14965 {{-1.0f, -1.0f, 0.0f}, 0xff002b7f},
14966 {{-1.0f, 1.0f, 0.0f}, 0xff002b7f},
14967 {{ 1.0f, -1.0f, 0.0f}, 0xff002b7f},
14968 {{ 1.0f, 1.0f, 0.0f}, 0xff002b7f},
14970 D3DCOLOR color;
14971 HRESULT hr;
14973 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
14974 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14976 hr = IDirect3DDevice9_BeginScene(device);
14977 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14979 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
14980 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14982 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
14983 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14984 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
14985 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14987 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
14988 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14989 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
14990 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14992 hr = IDirect3DDevice9_EndScene(device);
14993 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14995 color = getPixelColor(device, 1, 240);
14996 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
14997 color = getPixelColor(device, 638, 240);
14998 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
15000 color = getPixelColor(device, 1, 241);
15001 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
15002 color = getPixelColor(device, 638, 241);
15003 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
15006 static void clip_planes_test(void)
15008 IDirect3DSurface9 *offscreen_surface, *original_rt;
15009 IDirect3DTexture9 *offscreen = NULL;
15010 IDirect3DVertexShader9 *shader;
15011 IDirect3DDevice9 *device;
15012 IDirect3D9 *d3d;
15013 ULONG refcount;
15014 D3DCAPS9 caps;
15015 HWND window;
15016 HRESULT hr;
15018 static const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
15019 static const DWORD shader_code[] =
15021 0xfffe0200, /* vs_2_0 */
15022 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
15023 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
15024 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
15025 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
15026 0x0000ffff /* end */
15029 window = create_window();
15030 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15031 ok(!!d3d, "Failed to create a D3D object.\n");
15032 if (!(device = create_device(d3d, window, window, TRUE)))
15034 skip("Failed to create a D3D device, skipping tests.\n");
15035 goto done;
15038 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15039 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
15040 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
15042 skip("No vs_2_0 support, skipping tests.\n");
15043 IDirect3DDevice9_Release(device);
15044 goto done;
15047 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
15048 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
15050 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15051 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15052 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
15053 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15054 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
15055 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15056 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
15057 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15059 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
15060 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
15061 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
15062 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
15064 IDirect3DDevice9_SetClipPlane(device, 0, plane0);
15066 clip_planes(device, "Onscreen FFP");
15068 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
15069 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
15070 hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
15071 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
15072 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
15073 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
15075 clip_planes(device, "Offscreen FFP");
15077 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15078 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
15080 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
15081 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
15082 hr = IDirect3DDevice9_SetVertexShader(device, shader);
15083 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
15085 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15086 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
15088 clip_planes(device, "Onscreen vertex shader");
15090 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
15091 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
15093 clip_planes(device, "Offscreen vertex shader");
15095 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15096 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
15098 IDirect3DVertexShader9_Release(shader);
15099 IDirect3DSurface9_Release(original_rt);
15100 IDirect3DSurface9_Release(offscreen_surface);
15101 IDirect3DTexture9_Release(offscreen);
15102 refcount = IDirect3DDevice9_Release(device);
15103 ok(!refcount, "Device has %u references left.\n", refcount);
15104 done:
15105 IDirect3D9_Release(d3d);
15106 DestroyWindow(window);
15109 static void fp_special_test(void)
15111 /* Microsoft's assembler generates nan and inf with "1.#QNAN" and "1.#INF." respectively */
15112 static const DWORD vs_header[] =
15114 0xfffe0200, /* vs_2_0 */
15115 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
15116 0x05000051, 0xa00f0001, 0x7fc00000, 0xff800000, 0x7f800000, 0x00000000, /* def c1, nan, -inf, inf, 0 */
15117 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
15118 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
15121 static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001}; /* log r0.x, v1.x */
15122 static const DWORD vs_pow[] =
15123 {0x03000020, 0x80010000, 0x90000001, 0x90000001}; /* pow r0.x, v1.x, v1.x */
15124 static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001}; /* nrm r0.xyz, v1.x */
15125 static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001}; /* rcp r0.x, v1.x */
15126 static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001}; /* rcp r0.x, -v1.x */
15127 static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001}; /* rsq r0.x, v1.x */
15128 static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001}; /* rsq r0.x, -v1.x */
15129 static const DWORD vs_lit[] = {0x02000010, 0x800f0000, 0x90000001, /* lit r0, v1.xxxx */
15130 0x02000001, 0x80010000, 0x80aa0000}; /* mov r0.x, v0.z */
15131 static const DWORD vs_def1[] = {0x02000001, 0x80010000, 0xa0000001}; /* mov r0.x, c1.x */
15132 static const DWORD vs_def2[] = {0x02000001, 0x80010000, 0xa0550001}; /* mov r0.x, c1.y */
15133 static const DWORD vs_def3[] = {0x02000001, 0x80010000, 0xa0aa0001}; /* mov r0.x, c1.z */
15135 static const DWORD vs_footer[] =
15137 0x03000005, 0x80020000, 0x80000000, 0xa0ff0000, /* mul r0.y, r0.x, c0.w */
15138 0x0300000d, 0x80040000, 0x80000000, 0x80550000, /* sge r0.z, r0.x, r0.y */
15139 0x0300000d, 0x80020000, 0x80e40000, 0x80000000, /* sge r0.y, r0, r0.x */
15140 0x03000005, 0x80040000, 0x80550000, 0x80e40000, /* mul r0.z, r0.y, r0 */
15141 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
15142 0x0300000c, 0x80020000, 0x80000000, 0x80000000, /* slt r0.y, r0.x, r0.x */
15143 0x03000002, 0x80040000, 0x80550000, 0x80550000, /* add r0.z, r0.y, r0.y */
15144 0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000, /* slt r0.y, c0.x, r0.w */
15145 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
15146 0x03000002, 0x80040000, 0x81550000, 0xa0e40000, /* add r0.z, -r0.y, c0 */
15147 0x0300000c, 0x80080000, 0xa0000000, 0x80e40000, /* slt r0.w, c0.x, r0 */
15148 0x03000005, 0x80040000, 0x80ff0000, 0x80e40000, /* mul r0.z, r0.w, r0 */
15149 0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000, /* mad r0.y, r0.z, c0, r0 */
15150 0x02000001, 0xe0030000, 0x80e40000, /* mov oT0.xy, r0 */
15151 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
15152 0x0000ffff, /* end */
15155 static const struct
15157 const char *name;
15158 const DWORD *ops;
15159 DWORD size;
15160 D3DCOLOR r500;
15161 D3DCOLOR r600;
15162 D3DCOLOR nv40;
15163 D3DCOLOR nv50;
15164 D3DCOLOR warp;
15166 vs_body[] =
15168 /* The basic ideas here are:
15169 * 2.0 * +/-INF == +/-INF
15170 * NAN != NAN
15172 * The vertex shader value is written to the red component, with 0.0
15173 * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
15174 * result in 0x00. The pixel shader value is written to the green
15175 * component, but here 0.0 also results in 0x00. The actual value is
15176 * written to the blue component.
15178 * There are considerable differences between graphics cards in how
15179 * these are handled, but pow and nrm never generate INF or NAN on
15180 * real hardware. */
15181 {"log", vs_log, sizeof(vs_log), 0x00000000, 0x00000000, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
15182 {"pow", vs_pow, sizeof(vs_pow), 0x000000ff, 0x000000ff, 0x0000ff00, 0x000000ff, 0x00008000},
15183 {"nrm", vs_nrm, sizeof(vs_nrm), 0x00ff0000, 0x00ff0000, 0x0000ff00, 0x00ff0000, 0x00008000},
15184 {"rcp1", vs_rcp1, sizeof(vs_rcp1), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
15185 {"rcp2", vs_rcp2, sizeof(vs_rcp2), 0x000000ff, 0x00000000, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
15186 {"rsq1", vs_rsq1, sizeof(vs_rsq1), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
15187 {"rsq2", vs_rsq2, sizeof(vs_rsq2), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
15188 {"lit", vs_lit, sizeof(vs_lit), 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
15189 {"def1", vs_def1, sizeof(vs_def1), 0x000000ff, 0x00007f00, 0x0000ff00, 0x00007f00, 0x00008000},
15190 {"def2", vs_def2, sizeof(vs_def2), 0x00ff0000, 0x00ff7f00, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
15191 {"def3", vs_def3, sizeof(vs_def3), 0x00ff00ff, 0x00ff7f00, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
15194 static const DWORD ps_code[] =
15196 0xffff0200, /* ps_2_0 */
15197 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
15198 0x0200001f, 0x80000000, 0xb0030000, /* dcl t0.xy */
15199 0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000, /* max r1.x, t0, c0 */
15200 0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000, /* min r0.x, t0, c0 */
15201 0x03000002, 0x80010000, 0x80e40000, 0x81e40001, /* add r0.x, r0, -r1 */
15202 0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000, /* mad r1.x, t0, c0.w. -t0 */
15203 0x02000023, 0x80010002, 0x80e40001, /* abs r2.x, r1 */
15204 0x02000023, 0x80010000, 0x80e40000, /* abs r0.x, r0 */
15205 0x02000023, 0x80010001, 0xb0e40000, /* abs r1.x, t0 */
15206 0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r2, c0.z, c0 */
15207 0x02000023, 0x80010002, 0x80e40002, /* abs r2.x, r2 */
15208 0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r1.x, -r1, c0.z, c0 */
15209 0x02000023, 0x80010001, 0x80e40001, /* abs r1.x, r1 */
15210 0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r3.x, -r2, c0.z, c0 */
15211 0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r1, c0.z, c0 */
15212 0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000, /* cmp r0.x, -r0, c0.y, c0 */
15213 0x03000005, 0x80010002, 0x80e40002, 0x80e40003, /* mul r2.x, r2, r3 */
15214 0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000, /* cmp r0.x, -r2, c0.z, r0 */
15215 0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000, /* cmp r0.y, -r1.x, r0.x, c0.x */
15216 0x02000001, 0x80050000, 0xb0c90000, /* mov r0.xz, t0.yzxw */
15217 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.w, c0.z */
15218 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15219 0x0000ffff, /* end */
15222 struct
15224 float x, y, z;
15225 float s;
15227 quad[] =
15229 { -1.0f, 1.0f, 0.0f, 0.0f},
15230 { 1.0f, 1.0f, 1.0f, 0.0f},
15231 { -1.0f, -1.0f, 0.0f, 0.0f},
15232 { 1.0f, -1.0f, 1.0f, 0.0f},
15235 IDirect3DPixelShader9 *ps;
15236 IDirect3DDevice9 *device;
15237 UINT body_size = 0;
15238 IDirect3D9 *d3d;
15239 DWORD *vs_code;
15240 ULONG refcount;
15241 D3DCAPS9 caps;
15242 HWND window;
15243 HRESULT hr;
15244 UINT i;
15246 window = create_window();
15247 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15248 ok(!!d3d, "Failed to create a D3D object.\n");
15249 if (!(device = create_device(d3d, window, window, TRUE)))
15251 skip("Failed to create a D3D device, skipping tests.\n");
15252 goto done;
15255 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15256 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
15257 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
15259 skip("No shader model 2.0 support, skipping floating point specials test.\n");
15260 IDirect3DDevice9_Release(device);
15261 goto done;
15264 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
15265 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15267 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
15268 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
15269 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15270 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
15272 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
15273 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15275 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
15276 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
15278 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
15280 if (vs_body[i].size > body_size) body_size = vs_body[i].size;
15283 vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
15284 memcpy(vs_code, vs_header, sizeof(vs_header));
15286 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
15288 DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
15289 IDirect3DVertexShader9 *vs;
15290 D3DCOLOR color;
15292 memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
15293 offset += vs_body[i].size / sizeof(*vs_body[i].ops);
15294 memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
15296 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
15297 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
15298 hr = IDirect3DDevice9_SetVertexShader(device, vs);
15299 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
15301 hr = IDirect3DDevice9_BeginScene(device);
15302 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15303 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15304 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15305 hr = IDirect3DDevice9_EndScene(device);
15306 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15308 color = getPixelColor(device, 320, 240);
15309 ok(color_match(color, vs_body[i].r500, 1)
15310 || color_match(color, vs_body[i].r600, 1)
15311 || color_match(color, vs_body[i].nv40, 1)
15312 || color_match(color, vs_body[i].nv50, 1)
15313 || broken(color_match(color, vs_body[i].warp, 1)),
15314 "Expected color 0x%08x, 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
15315 vs_body[i].r500, vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
15317 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15318 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
15320 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
15321 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
15322 IDirect3DVertexShader9_Release(vs);
15325 HeapFree(GetProcessHeap(), 0, vs_code);
15327 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
15328 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
15329 IDirect3DPixelShader9_Release(ps);
15330 refcount = IDirect3DDevice9_Release(device);
15331 ok(!refcount, "Device has %u references left.\n", refcount);
15332 done:
15333 IDirect3D9_Release(d3d);
15334 DestroyWindow(window);
15337 static void srgbwrite_format_test(void)
15339 IDirect3D9 *d3d;
15340 IDirect3DSurface9 *rt, *backbuffer;
15341 IDirect3DTexture9 *texture;
15342 IDirect3DDevice9 *device;
15343 ULONG refcount;
15344 HWND window;
15345 HRESULT hr;
15346 int i;
15347 DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
15348 static const struct
15350 D3DFORMAT fmt;
15351 const char *name;
15353 formats[] =
15355 { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
15356 { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
15357 { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
15358 { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
15359 { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
15361 static const struct
15363 float x, y, z;
15364 float u, v;
15366 quad[] =
15368 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
15369 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
15370 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
15371 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
15374 window = create_window();
15375 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15376 ok(!!d3d, "Failed to create a D3D object.\n");
15377 if (!(device = create_device(d3d, window, window, TRUE)))
15379 skip("Failed to create a D3D device, skipping tests.\n");
15380 goto done;
15383 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
15384 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15385 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
15386 ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
15387 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
15388 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
15389 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
15390 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15392 for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
15394 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
15395 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
15397 skip("Format %s not supported as render target, skipping test.\n",
15398 formats[i].name);
15399 continue;
15402 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET,
15403 formats[i].fmt, D3DPOOL_DEFAULT, &texture, NULL);
15404 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
15405 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
15406 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
15408 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
15409 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
15410 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15411 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
15412 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
15413 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
15415 hr = IDirect3DDevice9_BeginScene(device);
15416 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15418 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
15419 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
15420 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
15421 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
15422 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15423 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15425 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
15426 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
15427 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
15428 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15429 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
15430 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
15431 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
15432 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
15433 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15434 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15435 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15436 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
15438 hr = IDirect3DDevice9_EndScene(device);
15439 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15441 IDirect3DSurface9_Release(rt);
15442 IDirect3DTexture9_Release(texture);
15444 color = getPixelColor(device, 360, 240);
15445 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
15446 D3DUSAGE_QUERY_SRGBWRITE,
15447 D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
15449 /* Big slop for R5G6B5 */
15450 ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
15451 formats[i].name, color_srgb, color);
15453 else
15455 /* Big slop for R5G6B5 */
15456 ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
15457 formats[i].name, color_rgb, color);
15460 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15461 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
15464 IDirect3DSurface9_Release(backbuffer);
15465 refcount = IDirect3DDevice9_Release(device);
15466 ok(!refcount, "Device has %u references left.\n", refcount);
15467 done:
15468 IDirect3D9_Release(d3d);
15469 DestroyWindow(window);
15472 static void ds_size_test(void)
15474 IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
15475 IDirect3DDevice9 *device;
15476 DWORD num_passes;
15477 IDirect3D9 *d3d;
15478 ULONG refcount;
15479 HWND window;
15480 HRESULT hr;
15482 static const struct
15484 float x, y, z;
15486 quad[] =
15488 {-1.0f, -1.0f, 0.0f},
15489 {-1.0f, 1.0f, 0.0f},
15490 { 1.0f, -1.0f, 0.0f},
15491 { 1.0f, 1.0f, 0.0f},
15494 window = create_window();
15495 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15496 ok(!!d3d, "Failed to create a D3D object.\n");
15497 if (!(device = create_device(d3d, window, window, TRUE)))
15499 skip("Failed to create a D3D device, skipping tests.\n");
15500 goto done;
15503 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
15504 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
15505 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
15506 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#x.\n", hr);
15507 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
15508 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
15510 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
15511 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
15513 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
15514 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15515 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
15516 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15517 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
15518 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15519 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15520 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
15521 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
15522 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
15523 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
15524 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#x.\n", hr);
15525 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15526 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
15527 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15528 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
15529 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15530 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
15532 /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
15533 * but does not change the surface's contents. */
15534 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
15535 ok(SUCCEEDED(hr), "Target clear failed, hr %#x.\n", hr);
15536 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
15537 ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#x.\n", hr);
15538 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
15539 ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#x.\n", hr);
15541 /* Nvidia does not clear the surface(The color is still 0x000000ff), AMD does(the color is 0x00ff0000) */
15543 /* Turning on any depth-related state results in a ValidateDevice failure */
15544 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15545 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15546 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15547 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
15548 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
15549 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
15550 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15551 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15552 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15553 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15554 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
15555 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
15557 /* Try to draw with the device in an invalid state. */
15558 hr = IDirect3DDevice9_BeginScene(device);
15559 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15560 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15561 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15562 hr = IDirect3DDevice9_EndScene(device);
15563 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15565 /* Don't check the resulting draw unless we find an app that needs it. On
15566 * NVIDIA ValidateDevice() returns CONFLICTINGRENDERSTATE, so the result
15567 * is undefined. On AMD D3D seems to assume the stored Z buffer value is
15568 * 0.0 for all pixels, even those that are covered by the depth buffer. */
15570 hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
15571 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
15572 hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
15573 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
15574 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15575 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
15577 IDirect3DSurface9_Release(readback);
15578 IDirect3DSurface9_Release(ds);
15579 IDirect3DSurface9_Release(rt);
15580 IDirect3DSurface9_Release(old_rt);
15581 IDirect3DSurface9_Release(old_ds);
15582 refcount = IDirect3DDevice9_Release(device);
15583 ok(!refcount, "Device has %u references left.\n", refcount);
15584 done:
15585 IDirect3D9_Release(d3d);
15586 DestroyWindow(window);
15589 static void unbound_sampler_test(void)
15591 IDirect3DPixelShader9 *ps, *ps_cube, *ps_volume;
15592 IDirect3DSurface9 *rt, *old_rt;
15593 IDirect3DDevice9 *device;
15594 IDirect3D9 *d3d;
15595 ULONG refcount;
15596 D3DCAPS9 caps;
15597 DWORD color;
15598 HWND window;
15599 HRESULT hr;
15601 static const DWORD ps_code[] =
15603 0xffff0200, /* ps_2_0 */
15604 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
15605 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
15606 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
15607 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15608 0x0000ffff, /* end */
15610 static const DWORD ps_code_cube[] =
15612 0xffff0200, /* ps_2_0 */
15613 0x0200001f, 0x98000000, 0xa00f0800, /* dcl_cube s0 */
15614 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
15615 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
15616 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15617 0x0000ffff, /* end */
15619 static const DWORD ps_code_volume[] =
15621 0xffff0200, /* ps_2_0 */
15622 0x0200001f, 0xa0000000, 0xa00f0800, /* dcl_volume s0 */
15623 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
15624 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
15625 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15626 0x0000ffff, /* end */
15629 static const struct
15631 float x, y, z;
15632 float u, v;
15634 quad[] =
15636 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
15637 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
15638 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
15639 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
15642 window = create_window();
15643 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15644 ok(!!d3d, "Failed to create a D3D object.\n");
15645 if (!(device = create_device(d3d, window, window, TRUE)))
15647 skip("Failed to create a D3D device, skipping tests.\n");
15648 goto done;
15651 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15652 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
15653 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
15655 skip("No ps_2_0 support, skipping tests.\n");
15656 IDirect3DDevice9_Release(device);
15657 goto done;
15659 if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP) || !(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
15661 skip("No cube / volume texture support, skipping tests.\n");
15662 IDirect3DDevice9_Release(device);
15663 goto done;
15666 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15667 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStage failed, %#x.\n", hr);
15669 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
15670 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
15671 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_cube, &ps_cube);
15672 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
15673 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_volume, &ps_volume);
15674 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
15676 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
15677 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
15679 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
15680 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
15682 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15683 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
15685 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 );
15686 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
15688 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x56ffffff, 1.0f, 0);
15689 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
15691 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15692 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
15694 hr = IDirect3DDevice9_BeginScene(device);
15695 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15696 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15697 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15698 hr = IDirect3DDevice9_EndScene(device);
15699 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15701 color = getPixelColorFromSurface(rt, 32, 32);
15702 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
15704 /* Now try with a cube texture */
15705 hr = IDirect3DDevice9_SetPixelShader(device, ps_cube);
15706 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
15708 hr = IDirect3DDevice9_BeginScene(device);
15709 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15710 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15711 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15712 hr = IDirect3DDevice9_EndScene(device);
15713 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15715 color = getPixelColorFromSurface(rt, 32, 32);
15716 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
15718 /* And then with a volume texture */
15719 hr = IDirect3DDevice9_SetPixelShader(device, ps_volume);
15720 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
15722 hr = IDirect3DDevice9_BeginScene(device);
15723 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15724 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15725 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15726 hr = IDirect3DDevice9_EndScene(device);
15727 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15729 color = getPixelColorFromSurface(rt, 32, 32);
15730 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
15732 IDirect3DSurface9_Release(rt);
15733 IDirect3DSurface9_Release(old_rt);
15734 IDirect3DPixelShader9_Release(ps);
15735 IDirect3DPixelShader9_Release(ps_cube);
15736 IDirect3DPixelShader9_Release(ps_volume);
15737 refcount = IDirect3DDevice9_Release(device);
15738 ok(!refcount, "Device has %u references left.\n", refcount);
15739 done:
15740 IDirect3D9_Release(d3d);
15741 DestroyWindow(window);
15744 static void update_surface_test(void)
15746 static const BYTE blocks[][8] =
15748 {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, /* White */
15749 {0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Red */
15750 {0xe0, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00}, /* Yellow */
15751 {0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Green */
15752 {0xff, 0x07, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Cyan */
15753 {0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Blue */
15754 {0x1f, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Magenta */
15756 static const struct
15758 UINT x, y;
15759 D3DCOLOR color;
15761 expected_colors[] =
15763 { 18, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0xff)},
15764 { 57, 240, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff)},
15765 {109, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0xff)},
15766 {184, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
15767 {290, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
15768 {440, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
15769 {584, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
15771 static const struct
15773 float x, y, z, w;
15774 float u, v;
15776 tri[] =
15778 { 0.0f, 480.0f, 0.0f, 1.0f, 0.0f, 0.0f},
15779 { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
15780 {640.0f, 240.0f, 0.0f, 10.0f, 100.0f, 0.5f},
15782 static const RECT rect_2x2 = {0, 0, 2, 2};
15783 static const struct
15785 UINT src_level;
15786 UINT dst_level;
15787 const RECT *r;
15788 HRESULT hr;
15790 block_size_tests[] =
15792 {1, 0, NULL, D3D_OK},
15793 {0, 1, NULL, D3DERR_INVALIDCALL},
15794 {5, 4, NULL, D3DERR_INVALIDCALL},
15795 {4, 5, NULL, D3DERR_INVALIDCALL},
15796 {4, 5, &rect_2x2, D3DERR_INVALIDCALL},
15797 {5, 5, &rect_2x2, D3D_OK},
15800 IDirect3DSurface9 *src_surface, *dst_surface;
15801 IDirect3DTexture9 *src_tex, *dst_tex;
15802 IDirect3DDevice9 *device;
15803 IDirect3D9 *d3d;
15804 ULONG refcount;
15805 UINT count, i;
15806 HWND window;
15807 HRESULT hr;
15809 window = create_window();
15810 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15811 ok(!!d3d, "Failed to create a D3D object.\n");
15812 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15813 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1)))
15815 skip("DXT1 not supported, skipping tests.\n");
15816 goto done;
15818 if (!(device = create_device(d3d, window, window, TRUE)))
15820 skip("Failed to create a D3D device, skipping tests.\n");
15821 goto done;
15824 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &src_tex, NULL);
15825 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
15826 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &dst_tex, NULL);
15827 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
15829 count = IDirect3DTexture9_GetLevelCount(src_tex);
15830 ok(count == 7, "Got level count %u, expected 7.\n", count);
15832 for (i = 0; i < count; ++i)
15834 UINT row_count, block_count, x, y;
15835 D3DSURFACE_DESC desc;
15836 BYTE *row, *block;
15837 D3DLOCKED_RECT r;
15839 hr = IDirect3DTexture9_GetLevelDesc(src_tex, i, &desc);
15840 ok(SUCCEEDED(hr), "Failed to get level desc, hr %#x.\n", hr);
15842 hr = IDirect3DTexture9_LockRect(src_tex, i, &r, NULL, 0);
15843 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
15845 row_count = ((desc.Height + 3) & ~3) / 4;
15846 block_count = ((desc.Width + 3) & ~3) / 4;
15847 row = r.pBits;
15849 for (y = 0; y < row_count; ++y)
15851 block = row;
15852 for (x = 0; x < block_count; ++x)
15854 memcpy(block, blocks[i], sizeof(blocks[i]));
15855 block += sizeof(blocks[i]);
15857 row += r.Pitch;
15860 hr = IDirect3DTexture9_UnlockRect(src_tex, i);
15861 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
15864 for (i = 0; i < sizeof(block_size_tests) / sizeof(*block_size_tests); ++i)
15866 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, block_size_tests[i].src_level, &src_surface);
15867 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15868 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, block_size_tests[i].dst_level, &dst_surface);
15869 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15871 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, block_size_tests[i].r, dst_surface, NULL);
15872 ok(hr == block_size_tests[i].hr, "Update surface returned %#x for test %u, expected %#x.\n",
15873 hr, i, block_size_tests[i].hr);
15875 IDirect3DSurface9_Release(dst_surface);
15876 IDirect3DSurface9_Release(src_surface);
15879 for (i = 0; i < count; ++i)
15881 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, i, &src_surface);
15882 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15883 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, i, &dst_surface);
15884 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15886 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, NULL, dst_surface, NULL);
15887 ok(SUCCEEDED(hr), "Failed to update surface at level %u, hr %#x.\n", i, hr);
15889 IDirect3DSurface9_Release(dst_surface);
15890 IDirect3DSurface9_Release(src_surface);
15893 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15894 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15895 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
15896 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15897 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
15898 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15899 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)dst_tex);
15900 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
15901 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
15902 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
15903 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
15904 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
15906 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
15907 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
15909 hr = IDirect3DDevice9_BeginScene(device);
15910 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15911 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 1, tri, sizeof(*tri));
15912 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15913 hr = IDirect3DDevice9_EndScene(device);
15914 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15916 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15918 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
15919 ok(color_match(color, expected_colors[i].color, 0),
15920 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15921 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15924 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15925 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
15927 IDirect3DTexture9_Release(dst_tex);
15928 IDirect3DTexture9_Release(src_tex);
15929 refcount = IDirect3DDevice9_Release(device);
15930 ok(!refcount, "Device has %u references left.\n", refcount);
15931 done:
15932 IDirect3D9_Release(d3d);
15933 DestroyWindow(window);
15936 static void multisample_get_rtdata_test(void)
15938 IDirect3DSurface9 *original_ds, *original_rt, *rt, *readback;
15939 IDirect3DDevice9 *device;
15940 IDirect3D9 *d3d;
15941 ULONG refcount;
15942 HWND window;
15943 HRESULT hr;
15945 window = create_window();
15946 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15947 ok(!!d3d, "Failed to create a D3D object.\n");
15948 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15949 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15951 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping tests.\n");
15952 goto done;
15954 if (!(device = create_device(d3d, window, window, TRUE)))
15956 skip("Failed to create a D3D device, skipping tests.\n");
15957 goto done;
15960 hr = IDirect3DDevice9_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
15961 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
15962 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
15963 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_A8R8G8B8,
15964 D3DPOOL_SYSTEMMEM, &readback, NULL);
15965 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
15967 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
15968 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
15969 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
15970 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
15972 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15973 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15974 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15975 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15977 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
15978 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15979 hr = IDirect3DDevice9_GetRenderTargetData(device, rt, readback);
15980 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
15982 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
15983 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15984 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15985 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
15987 IDirect3DSurface9_Release(original_ds);
15988 IDirect3DSurface9_Release(original_rt);
15989 IDirect3DSurface9_Release(readback);
15990 IDirect3DSurface9_Release(rt);
15991 refcount = IDirect3DDevice9_Release(device);
15992 ok(!refcount, "Device has %u references left.\n", refcount);
15993 done:
15994 IDirect3D9_Release(d3d);
15995 DestroyWindow(window);
15998 static void multisampled_depth_buffer_test(void)
16000 IDirect3DDevice9 *device = 0;
16001 IDirect3DSurface9 *original_rt, *rt, *readback, *ds, *original_ds;
16002 IDirect3D9 *d3d;
16003 D3DCAPS9 caps;
16004 HRESULT hr;
16005 D3DPRESENT_PARAMETERS present_parameters;
16006 unsigned int i;
16007 static const struct
16009 float x, y, z;
16010 D3DCOLOR color;
16012 quad_1[] =
16014 { -1.0f, 1.0f, 0.0f, 0xffff0000},
16015 { 1.0f, 1.0f, 1.0f, 0xffff0000},
16016 { -1.0f, -1.0f, 0.0f, 0xffff0000},
16017 { 1.0f, -1.0f, 1.0f, 0xffff0000},
16019 quad_2[] =
16021 { -1.0f, 1.0f, 1.0f, 0xff0000ff},
16022 { 1.0f, 1.0f, 0.0f, 0xff0000ff},
16023 { -1.0f, -1.0f, 1.0f, 0xff0000ff},
16024 { 1.0f, -1.0f, 0.0f, 0xff0000ff},
16026 static const struct
16028 UINT x, y;
16029 D3DCOLOR color;
16031 expected_colors[] =
16033 { 80, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
16034 {240, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
16035 {400, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
16036 {560, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
16037 { 80, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
16038 {240, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
16039 {400, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
16040 {560, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
16043 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16044 ok(!!d3d, "Failed to create a D3D object.\n");
16046 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
16047 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
16049 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled depth buffer test.\n");
16050 IDirect3D9_Release(d3d);
16051 return;
16053 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
16054 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
16056 skip("Multisampling not supported for D3DFMT_D24S8, skipping multisampled depth buffer test.\n");
16057 IDirect3D9_Release(d3d);
16058 return;
16061 ZeroMemory(&present_parameters, sizeof(present_parameters));
16062 present_parameters.Windowed = TRUE;
16063 present_parameters.hDeviceWindow = create_window();
16064 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
16065 present_parameters.BackBufferWidth = 640;
16066 present_parameters.BackBufferHeight = 480;
16067 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
16068 present_parameters.EnableAutoDepthStencil = TRUE;
16069 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
16070 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
16072 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16073 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
16074 &present_parameters, &device);
16075 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
16077 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16078 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
16079 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
16081 skip("No unconditional NP2 texture support, skipping multisampled depth buffer test.\n");
16082 goto cleanup;
16085 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
16086 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
16087 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
16088 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
16089 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
16090 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
16092 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
16093 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
16094 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
16095 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
16097 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16098 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16099 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
16100 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16101 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16102 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16103 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
16104 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16105 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
16106 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
16108 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
16109 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16111 /* Render onscreen and then offscreen */
16112 hr = IDirect3DDevice9_BeginScene(device);
16113 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16114 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
16115 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16116 hr = IDirect3DDevice9_EndScene(device);
16117 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16119 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, rt, NULL, D3DTEXF_POINT);
16120 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
16121 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
16122 ok(SUCCEEDED(hr), "Failed to set 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_2, sizeof(*quad_2));
16127 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16128 hr = IDirect3DDevice9_EndScene(device);
16129 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16131 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, readback, NULL, D3DTEXF_POINT);
16132 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
16134 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16136 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
16137 ok(color_match(color, expected_colors[i].color, 1),
16138 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16139 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16142 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
16143 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
16144 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16145 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16147 /* Render offscreen and then onscreen */
16148 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16149 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16150 IDirect3DSurface9_Release(ds);
16151 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
16152 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
16153 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#x.\n", hr);
16154 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16155 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16157 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
16158 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16160 hr = IDirect3DDevice9_BeginScene(device);
16161 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16162 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
16163 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16164 hr = IDirect3DDevice9_EndScene(device);
16165 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16167 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
16168 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
16169 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16170 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16172 hr = IDirect3DDevice9_BeginScene(device);
16173 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16174 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
16175 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16176 hr = IDirect3DDevice9_EndScene(device);
16177 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16179 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
16180 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
16182 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16184 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
16185 ok(color_match(color, expected_colors[i].color, 1),
16186 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16187 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16190 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16191 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16193 IDirect3DSurface9_Release(ds);
16194 IDirect3DSurface9_Release(readback);
16195 IDirect3DSurface9_Release(rt);
16196 IDirect3DSurface9_Release(original_rt);
16197 cleanup_device(device);
16199 ZeroMemory(&present_parameters, sizeof(present_parameters));
16200 present_parameters.Windowed = TRUE;
16201 present_parameters.hDeviceWindow = create_window();
16202 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
16203 present_parameters.BackBufferWidth = 640;
16204 present_parameters.BackBufferHeight = 480;
16205 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
16206 present_parameters.EnableAutoDepthStencil = TRUE;
16207 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
16208 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
16210 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16211 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
16212 &present_parameters, &device);
16213 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
16215 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
16216 ok(SUCCEEDED(hr), "Failed to clear depth buffer, hr %#x.\n", hr);
16218 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
16219 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
16220 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
16221 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
16222 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
16223 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
16224 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
16225 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
16226 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
16228 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
16229 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
16230 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
16231 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
16232 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
16233 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16234 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16235 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16237 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16238 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16239 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
16240 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16241 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16242 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16243 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
16244 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16245 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
16246 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
16248 /* Render to a multisampled offscreen frame buffer and then blit to
16249 * the onscreen (not multisampled) frame buffer. */
16250 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
16251 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16253 hr = IDirect3DDevice9_BeginScene(device);
16254 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16255 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
16256 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16257 hr = IDirect3DDevice9_EndScene(device);
16258 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16260 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
16261 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
16262 hr = IDirect3DDevice9_StretchRect(device, ds, NULL, original_ds, NULL, D3DTEXF_POINT);
16263 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
16265 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16266 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16267 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
16268 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16270 hr = IDirect3DDevice9_BeginScene(device);
16271 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16272 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
16273 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16274 hr = IDirect3DDevice9_EndScene(device);
16275 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16277 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
16278 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
16280 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16282 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
16283 ok(color_match(color, expected_colors[i].color, 1),
16284 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16285 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16288 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16289 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16291 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16292 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16293 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16294 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
16296 IDirect3DSurface9_Release(original_ds);
16297 IDirect3DSurface9_Release(original_rt);
16298 IDirect3DSurface9_Release(ds);
16299 IDirect3DSurface9_Release(readback);
16300 IDirect3DSurface9_Release(rt);
16301 cleanup:
16302 cleanup_device(device);
16303 IDirect3D9_Release(d3d);
16306 static void resz_test(void)
16308 IDirect3DDevice9 *device = 0;
16309 IDirect3DSurface9 *rt, *original_rt, *ds, *readback, *intz_ds;
16310 D3DCAPS9 caps;
16311 HRESULT hr;
16312 D3DPRESENT_PARAMETERS present_parameters;
16313 unsigned int i;
16314 static const DWORD ps_code[] =
16316 0xffff0200, /* ps_2_0 */
16317 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
16318 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
16319 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
16320 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
16321 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
16322 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
16323 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
16324 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
16325 0x02000001, 0x800f0800, 0x80e40001, /* mov oC0, r1 */
16326 0x0000ffff, /* end */
16328 static const struct
16330 float x, y, z;
16331 float s, t, p, q;
16333 quad[] =
16335 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
16336 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
16337 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
16338 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
16340 static const struct
16342 UINT x, y;
16343 D3DCOLOR color;
16345 expected_colors[] =
16347 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
16348 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
16349 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
16350 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
16351 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
16352 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
16353 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
16354 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
16356 IDirect3DTexture9 *texture;
16357 IDirect3DPixelShader9 *ps;
16358 IDirect3D9 *d3d;
16359 DWORD value;
16361 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16362 ok(!!d3d, "Failed to create a D3D object.\n");
16364 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
16365 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
16367 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
16368 IDirect3D9_Release(d3d);
16369 return;
16371 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
16372 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
16374 skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
16375 IDirect3D9_Release(d3d);
16376 return;
16379 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
16380 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
16382 skip("No INTZ support, skipping RESZ test.\n");
16383 IDirect3D9_Release(d3d);
16384 return;
16387 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
16388 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'))))
16390 skip("No RESZ support, skipping RESZ test.\n");
16391 IDirect3D9_Release(d3d);
16392 return;
16395 ZeroMemory(&present_parameters, sizeof(present_parameters));
16396 present_parameters.Windowed = TRUE;
16397 present_parameters.hDeviceWindow = create_window();
16398 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
16399 present_parameters.BackBufferWidth = 640;
16400 present_parameters.BackBufferHeight = 480;
16401 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
16402 present_parameters.EnableAutoDepthStencil = FALSE;
16403 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
16404 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
16406 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16407 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
16408 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
16410 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16411 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
16412 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
16414 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
16415 cleanup_device(device);
16416 IDirect3D9_Release(d3d);
16417 return;
16419 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
16421 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
16422 cleanup_device(device);
16423 IDirect3D9_Release(d3d);
16424 return;
16427 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
16428 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
16430 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
16431 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
16432 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
16433 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
16434 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
16435 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#x.\n", hr);
16436 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
16437 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
16438 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
16440 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
16441 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
16442 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
16443 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
16444 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
16445 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
16446 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16447 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
16448 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
16449 IDirect3DSurface9_Release(intz_ds);
16450 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
16451 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
16453 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
16454 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
16455 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
16456 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16457 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
16458 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16459 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16460 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16461 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16462 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16464 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
16465 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16466 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
16467 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16468 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
16469 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16470 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
16471 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16472 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
16473 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16475 /* Render offscreen (multisampled), blit the depth buffer
16476 * into the INTZ texture and then check its contents */
16477 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
16478 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16479 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16480 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16481 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
16482 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16484 hr = IDirect3DDevice9_BeginScene(device);
16485 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16486 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16487 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16489 /* The destination depth texture has to be bound to sampler 0 */
16490 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16491 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16493 /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
16494 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
16495 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16496 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
16497 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16498 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
16499 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16500 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16501 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16502 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
16503 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16504 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16505 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16506 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
16507 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16509 /* The actual multisampled depth buffer resolve happens here */
16510 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16511 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16512 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
16513 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
16515 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16516 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16517 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16518 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16519 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16520 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16522 /* Read the depth values back */
16523 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16524 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16525 hr = IDirect3DDevice9_EndScene(device);
16526 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16528 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16530 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
16531 ok(color_match(color, expected_colors[i].color, 1),
16532 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16533 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16536 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16537 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16539 IDirect3DSurface9_Release(ds);
16540 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16541 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16542 IDirect3DTexture9_Release(texture);
16543 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16544 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16545 IDirect3DPixelShader9_Release(ps);
16546 IDirect3DSurface9_Release(readback);
16547 IDirect3DSurface9_Release(original_rt);
16548 IDirect3DSurface9_Release(rt);
16549 cleanup_device(device);
16551 ZeroMemory(&present_parameters, sizeof(present_parameters));
16552 present_parameters.Windowed = TRUE;
16553 present_parameters.hDeviceWindow = create_window();
16554 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
16555 present_parameters.BackBufferWidth = 640;
16556 present_parameters.BackBufferHeight = 480;
16557 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
16558 present_parameters.EnableAutoDepthStencil = TRUE;
16559 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
16560 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
16562 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16563 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
16564 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
16566 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
16567 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
16568 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
16569 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
16570 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
16571 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
16572 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
16573 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
16574 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
16575 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
16576 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
16577 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
16578 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
16579 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16580 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
16581 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16582 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
16583 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
16584 IDirect3DSurface9_Release(intz_ds);
16585 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
16586 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
16588 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
16589 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
16590 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
16591 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16592 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
16593 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16594 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16595 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16596 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16597 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16599 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
16600 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16601 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
16602 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16603 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
16604 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16605 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
16606 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16607 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
16608 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16610 /* Render onscreen, blit the depth buffer into the INTZ texture
16611 * and then check its contents */
16612 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16613 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16614 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16615 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16616 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
16617 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16619 hr = IDirect3DDevice9_BeginScene(device);
16620 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16621 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16622 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16623 hr = IDirect3DDevice9_EndScene(device);
16624 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16626 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16627 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16629 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
16630 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16631 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
16632 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16633 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
16634 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16635 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16636 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16637 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
16638 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16639 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16640 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16641 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
16642 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16644 /* The actual multisampled depth buffer resolve happens here */
16645 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16646 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16647 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
16648 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
16650 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
16651 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16652 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16653 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16654 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16655 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16657 /* Read the depth values back */
16658 hr = IDirect3DDevice9_BeginScene(device);
16659 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16660 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16661 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16662 hr = IDirect3DDevice9_EndScene(device);
16663 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16665 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16667 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
16668 ok(color_match(color, expected_colors[i].color, 1),
16669 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16670 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16673 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16674 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16677 /* Test edge cases - try with no texture at all */
16678 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16679 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16680 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16681 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16682 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16683 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16684 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16685 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16687 hr = IDirect3DDevice9_BeginScene(device);
16688 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16689 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16690 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16691 hr = IDirect3DDevice9_EndScene(device);
16692 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16694 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16695 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16697 /* With a non-multisampled depth buffer */
16698 IDirect3DSurface9_Release(ds);
16699 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
16700 D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
16701 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
16703 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
16704 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16705 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16706 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16707 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16708 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16710 hr = IDirect3DDevice9_BeginScene(device);
16711 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16712 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16713 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16715 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16716 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16718 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
16719 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16720 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
16721 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16722 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
16723 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16724 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16725 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16726 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
16727 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16728 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16729 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16730 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
16731 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16732 hr = IDirect3DDevice9_EndScene(device);
16733 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16735 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16736 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16738 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16739 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16741 /* Read the depth values back. */
16742 hr = IDirect3DDevice9_BeginScene(device);
16743 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16744 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16745 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16746 hr = IDirect3DDevice9_EndScene(device);
16747 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16749 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16751 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
16752 ok(color_match(color, expected_colors[i].color, 1),
16753 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16754 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16757 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16758 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16760 /* Without a current depth-stencil buffer set */
16761 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16762 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16763 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16764 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16766 hr = IDirect3DDevice9_BeginScene(device);
16767 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16768 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16769 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16770 hr = IDirect3DDevice9_EndScene(device);
16771 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16773 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16774 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16776 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16777 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16778 IDirect3DSurface9_Release(ds);
16779 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16780 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16781 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16782 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16783 IDirect3DTexture9_Release(texture);
16784 IDirect3DPixelShader9_Release(ps);
16785 IDirect3DSurface9_Release(readback);
16786 IDirect3DSurface9_Release(original_rt);
16787 cleanup_device(device);
16788 IDirect3D9_Release(d3d);
16791 static void zenable_test(void)
16793 static const struct
16795 struct vec4 position;
16796 D3DCOLOR diffuse;
16798 tquad[] =
16800 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
16801 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xff00ff00},
16802 {{640.0f, 480.0f, 1.5f, 1.0f}, 0xff00ff00},
16803 {{640.0f, 0.0f, 1.5f, 1.0f}, 0xff00ff00},
16805 IDirect3DDevice9 *device;
16806 IDirect3D9 *d3d;
16807 D3DCOLOR color;
16808 ULONG refcount;
16809 D3DCAPS9 caps;
16810 HWND window;
16811 HRESULT hr;
16812 UINT x, y;
16813 UINT i, j;
16814 UINT test;
16815 IDirect3DSurface9 *ds;
16817 window = create_window();
16818 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16819 ok(!!d3d, "Failed to create a D3D object.\n");
16820 if (!(device = create_device(d3d, window, window, TRUE)))
16822 skip("Failed to create a D3D device, skipping tests.\n");
16823 goto done;
16826 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
16827 ok(SUCCEEDED(hr), "Failed to get depth stencil surface, hr %#x.\n", hr);
16829 for (test = 0; test < 2; ++test)
16831 /* The Windows 8 testbot (WARP) appears to clip with
16832 * ZENABLE = D3DZB_TRUE and no depth buffer set. */
16833 static const D3DCOLOR expected_broken[] =
16835 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16836 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16837 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16838 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16841 if (!test)
16843 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16844 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
16846 else
16848 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
16849 ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
16850 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16851 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
16852 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.0f, 0);
16853 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16855 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
16856 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16858 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
16859 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16860 hr = IDirect3DDevice9_BeginScene(device);
16861 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16862 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
16863 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16864 hr = IDirect3DDevice9_EndScene(device);
16865 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16867 for (i = 0; i < 4; ++i)
16869 for (j = 0; j < 4; ++j)
16871 x = 80 * ((2 * j) + 1);
16872 y = 60 * ((2 * i) + 1);
16873 color = getPixelColor(device, x, y);
16874 ok(color_match(color, 0x0000ff00, 1)
16875 || broken(color_match(color, expected_broken[i * 4 + j], 1) && !test),
16876 "Expected color 0x0000ff00 at %u, %u, got 0x%08x, test %u.\n",
16877 x, y, color, test);
16881 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16882 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
16885 IDirect3DSurface9_Release(ds);
16887 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16888 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
16890 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
16891 && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
16893 static const DWORD vs_code[] =
16895 0xfffe0101, /* vs_1_1 */
16896 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
16897 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
16898 0x00000001, 0xd00f0000, 0x90e40000, /* mov oD0, v0 */
16899 0x0000ffff
16901 static const DWORD ps_code[] =
16903 0xffff0101, /* ps_1_1 */
16904 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
16905 0x0000ffff /* end */
16907 static const struct vec3 quad[] =
16909 {-1.0f, -1.0f, -0.5f},
16910 {-1.0f, 1.0f, -0.5f},
16911 { 1.0f, -1.0f, 1.5f},
16912 { 1.0f, 1.0f, 1.5f},
16914 static const D3DCOLOR expected[] =
16916 0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
16917 0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
16918 0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
16919 0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
16921 /* The Windows 8 testbot (WARP) appears to not clip z for regular
16922 * vertices either. */
16923 static const D3DCOLOR expected_broken[] =
16925 0x0020df20, 0x0060df60, 0x009fdf9f, 0x00dfdfdf,
16926 0x00209f20, 0x00609f60, 0x009f9f9f, 0x00df9fdf,
16927 0x00206020, 0x00606060, 0x009f609f, 0x00df60df,
16928 0x00202020, 0x00602060, 0x009f209f, 0x00df20df,
16931 IDirect3DVertexShader9 *vs;
16932 IDirect3DPixelShader9 *ps;
16934 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
16935 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16936 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
16937 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
16938 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
16939 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
16940 hr = IDirect3DDevice9_SetVertexShader(device, vs);
16941 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
16942 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16943 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
16945 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
16946 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16947 hr = IDirect3DDevice9_BeginScene(device);
16948 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16949 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16950 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16951 hr = IDirect3DDevice9_EndScene(device);
16952 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16954 for (i = 0; i < 4; ++i)
16956 for (j = 0; j < 4; ++j)
16958 x = 80 * ((2 * j) + 1);
16959 y = 60 * ((2 * i) + 1);
16960 color = getPixelColor(device, x, y);
16961 ok(color_match(color, expected[i * 4 + j], 1)
16962 || broken(color_match(color, expected_broken[i * 4 + j], 1)),
16963 "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
16967 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16968 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
16970 IDirect3DPixelShader9_Release(ps);
16971 IDirect3DVertexShader9_Release(vs);
16974 refcount = IDirect3DDevice9_Release(device);
16975 ok(!refcount, "Device has %u references left.\n", refcount);
16976 done:
16977 IDirect3D9_Release(d3d);
16978 DestroyWindow(window);
16981 static void fog_special_test(void)
16983 static const struct
16985 struct vec3 position;
16986 D3DCOLOR diffuse;
16988 quad[] =
16990 {{ -1.0f, -1.0f, 0.0f}, 0xff00ff00},
16991 {{ -1.0f, 1.0f, 0.0f}, 0xff00ff00},
16992 {{ 1.0f, -1.0f, 1.0f}, 0xff00ff00},
16993 {{ 1.0f, 1.0f, 1.0f}, 0xff00ff00}
16995 static const struct
16997 DWORD vertexmode, tablemode;
16998 BOOL vs, ps;
16999 D3DCOLOR color_left, color_right;
17001 tests[] =
17003 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, FALSE, 0x00ff0000, 0x00ff0000},
17004 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, TRUE, 0x00ff0000, 0x00ff0000},
17005 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, FALSE, 0x00ff0000, 0x00ff0000},
17006 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, TRUE, 0x00ff0000, 0x00ff0000},
17008 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, FALSE, 0x0000ff00, 0x00ff0000},
17009 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, TRUE, 0x0000ff00, 0x00ff0000},
17010 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, FALSE, 0x0000ff00, 0x00ff0000},
17011 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, TRUE, 0x0000ff00, 0x00ff0000},
17013 static const DWORD pixel_shader_code[] =
17015 0xffff0101, /* ps_1_1 */
17016 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
17017 0x0000ffff
17019 static const DWORD vertex_shader_code[] =
17021 0xfffe0101, /* vs_1_1 */
17022 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
17023 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
17024 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
17025 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
17026 0x0000ffff
17028 static const D3DMATRIX identity =
17030 1.0f, 0.0f, 0.0f, 0.0f,
17031 0.0f, 1.0f, 0.0f, 0.0f,
17032 0.0f, 0.0f, 1.0f, 0.0f,
17033 0.0f, 0.0f, 0.0f, 1.0f,
17034 }}};
17035 union
17037 float f;
17038 DWORD d;
17039 } conv;
17040 DWORD color;
17041 HRESULT hr;
17042 unsigned int i;
17043 IDirect3DPixelShader9 *ps;
17044 IDirect3DVertexShader9 *vs;
17045 IDirect3DDevice9 *device;
17046 IDirect3D9 *d3d;
17047 ULONG refcount;
17048 D3DCAPS9 caps;
17049 HWND window;
17051 window = create_window();
17052 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17053 ok(!!d3d, "Failed to create a D3D object.\n");
17054 if (!(device = create_device(d3d, window, window, TRUE)))
17056 skip("Failed to create a D3D device, skipping tests.\n");
17057 goto done;
17060 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17061 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17062 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
17064 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code, &vs);
17065 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
17067 else
17069 skip("Vertex Shaders not supported, skipping some fog tests.\n");
17070 vs = NULL;
17072 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
17074 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &ps);
17075 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
17077 else
17079 skip("Pixel Shaders not supported, skipping some fog tests.\n");
17080 ps = NULL;
17083 /* The table fog tests seem to depend on the projection matrix explicitly
17084 * being set to an identity matrix, even though that's the default.
17085 * (AMD Radeon HD 6310, Windows 7) */
17086 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
17087 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
17089 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
17090 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
17091 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
17092 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
17093 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
17094 ok(SUCCEEDED(hr), "Failed to enable fog, hr %#x.\n", hr);
17095 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffff0000);
17096 ok(SUCCEEDED(hr), "Failed to set fog color, hr %#x.\n", hr);
17098 conv.f = 0.5f;
17099 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, conv.d);
17100 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#x.\n", hr);
17101 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, conv.d);
17102 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#x.\n", hr);
17104 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
17106 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
17107 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
17109 if (!tests[i].vs)
17111 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
17112 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
17114 else if (vs)
17116 hr = IDirect3DDevice9_SetVertexShader(device, vs);
17117 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
17119 else
17121 continue;
17124 if (!tests[i].ps)
17126 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
17127 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
17129 else if (ps)
17131 hr = IDirect3DDevice9_SetPixelShader(device, ps);
17132 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
17134 else
17136 continue;
17139 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vertexmode);
17140 ok(SUCCEEDED(hr), "Failed to set fogvertexmode, hr %#x.\n", hr);
17141 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tablemode);
17142 ok(SUCCEEDED(hr), "Failed to set fogtablemode, hr %#x.\n", hr);
17144 hr = IDirect3DDevice9_BeginScene(device);
17145 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17146 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17147 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17148 hr = IDirect3DDevice9_EndScene(device);
17149 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17151 color = getPixelColor(device, 310, 240);
17152 ok(color_match(color, tests[i].color_left, 1),
17153 "Expected left color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_left, color, i);
17154 color = getPixelColor(device, 330, 240);
17155 ok(color_match(color, tests[i].color_right, 1),
17156 "Expected right color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_right, color, i);
17158 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17159 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
17162 if (vs)
17163 IDirect3DVertexShader9_Release(vs);
17164 if (ps)
17165 IDirect3DPixelShader9_Release(ps);
17166 refcount = IDirect3DDevice9_Release(device);
17167 ok(!refcount, "Device has %u references left.\n", refcount);
17168 done:
17169 IDirect3D9_Release(d3d);
17170 DestroyWindow(window);
17173 static void volume_srgb_test(void)
17175 HRESULT hr;
17176 unsigned int i, j;
17177 IDirect3DVolumeTexture9 *tex1, *tex2;
17178 D3DPOOL pool;
17179 D3DLOCKED_BOX locked_box;
17180 IDirect3DDevice9 *device;
17181 IDirect3D9 *d3d;
17182 D3DCOLOR color;
17183 ULONG refcount;
17184 HWND window;
17186 static const struct
17188 BOOL srgb;
17189 DWORD color;
17191 tests[] =
17193 /* Try toggling on and off */
17194 { FALSE, 0x007f7f7f },
17195 { TRUE, 0x00363636 },
17196 { FALSE, 0x007f7f7f },
17198 static const struct
17200 struct vec3 pos;
17201 struct vec3 texcrd;
17203 quad[] =
17205 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
17206 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
17207 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
17208 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
17211 window = create_window();
17212 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17213 ok(!!d3d, "Failed to create a D3D object.\n");
17214 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
17215 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_VOLUMETEXTURE, D3DFMT_A8R8G8B8) != D3D_OK)
17217 skip("D3DFMT_A8R8G8B8 volume textures with SRGBREAD not supported.\n");
17218 goto done;
17220 if (!(device = create_device(d3d, window, window, TRUE)))
17222 skip("Failed to create a D3D device, skipping tests.\n");
17223 goto done;
17226 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17227 ok(SUCCEEDED(hr), "Failed to set color op 0, hr %#x.\n", hr);
17228 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
17229 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17230 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
17231 ok(SUCCEEDED(hr), "Failed to set color op 0, hr %#x.\n", hr);
17232 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
17233 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
17235 for (i = 0; i < 2; i++)
17237 if (!i)
17238 pool = D3DPOOL_SYSTEMMEM;
17239 else
17240 pool = D3DPOOL_MANAGED;
17242 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, 0, D3DFMT_A8R8G8B8, pool, &tex1, NULL);
17243 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
17244 hr = IDirect3DVolumeTexture9_LockBox(tex1, 0, &locked_box, NULL, 0);
17245 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
17246 *((DWORD *)locked_box.pBits) = 0x7f7f7f7f;
17247 hr = IDirect3DVolumeTexture9_UnlockBox(tex1, 0);
17248 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
17250 if (!i)
17252 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, 0,
17253 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
17254 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
17255 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex1, (IDirect3DBaseTexture9 *)tex2);
17256 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17257 IDirect3DVolumeTexture9_Release(tex1);
17259 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex2);
17260 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17261 IDirect3DVolumeTexture9_Release(tex2);
17263 else
17265 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex1);
17266 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17267 IDirect3DVolumeTexture9_Release(tex1);
17270 for (j = 0; j < sizeof(tests) / sizeof(*tests); j++)
17272 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, tests[j].srgb);
17273 ok(SUCCEEDED(hr), "Failed to set srgb state, hr %#x.\n", hr);
17275 hr = IDirect3DDevice9_BeginScene(device);
17276 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17277 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17278 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17279 hr = IDirect3DDevice9_EndScene(device);
17280 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17282 color = getPixelColor(device, 320, 240);
17283 ok(color_match(color, tests[j].color, 2),
17284 "Expected color 0x%08x, got 0x%08x, i = %u, j = %u.\n", tests[j].color, color, i, j);
17286 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17287 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
17291 refcount = IDirect3DDevice9_Release(device);
17292 ok(!refcount, "Device has %u references left.\n", refcount);
17293 done:
17294 IDirect3D9_Release(d3d);
17295 DestroyWindow(window);
17298 static void volume_dxt5_test(void)
17300 IDirect3DVolumeTexture9 *texture;
17301 IDirect3DDevice9 *device;
17302 D3DLOCKED_BOX box;
17303 IDirect3D9 *d3d;
17304 unsigned int i;
17305 ULONG refcount;
17306 DWORD color;
17307 HWND window;
17308 HRESULT hr;
17310 static const char texture_data[] =
17312 /* A 8x4x2 texture consisting of 4 4x4 blocks. The colors of the blocks are red, green, blue and white. */
17313 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
17314 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
17315 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
17316 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
17318 static const struct
17320 struct vec3 position;
17321 struct vec3 texcrd;
17323 quads[] =
17325 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
17326 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
17327 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
17328 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
17330 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
17331 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
17332 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
17333 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
17335 static const DWORD expected_colors[] = {0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff};
17337 window = create_window();
17338 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17339 ok(!!d3d, "Failed to create a D3D object.\n");
17340 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17341 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_DXT5)))
17343 skip("DXT5 volume textures are not supported, skipping test.\n");
17344 goto done;
17346 if (!(device = create_device(d3d, window, window, TRUE)))
17348 skip("Failed to create a D3D device, skipping tests.\n");
17349 goto done;
17352 hr = IDirect3DDevice9_CreateVolumeTexture(device, 8, 4, 2, 1, 0, D3DFMT_DXT5,
17353 D3DPOOL_MANAGED, &texture, NULL);
17354 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
17356 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
17357 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
17358 memcpy(box.pBits, texture_data, sizeof(texture_data));
17359 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
17360 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
17362 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
17363 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
17364 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
17365 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17366 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17367 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17368 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
17369 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17370 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
17371 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17372 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
17373 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
17375 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
17376 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17377 hr = IDirect3DDevice9_BeginScene(device);
17378 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17379 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
17380 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17381 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
17382 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17383 hr = IDirect3DDevice9_EndScene(device);
17384 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17386 for (i = 0; i < 4; i++)
17388 color = getPixelColor(device, 80 + 160 * i, 240);
17389 ok (color_match(color, expected_colors[i], 1),
17390 "Expected color 0x%08x, got 0x%08x, case %u.\n", expected_colors[i], color, i);
17393 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17394 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17395 IDirect3DVolumeTexture9_Release(texture);
17396 refcount = IDirect3DDevice9_Release(device);
17397 ok(!refcount, "Device has %u references left.\n", refcount);
17398 done:
17399 IDirect3D9_Release(d3d);
17400 DestroyWindow(window);
17403 static void volume_v16u16_test(void)
17405 IDirect3DVolumeTexture9 *texture;
17406 IDirect3DPixelShader9 *shader;
17407 IDirect3DDevice9 *device;
17408 D3DLOCKED_BOX box;
17409 IDirect3D9 *d3d;
17410 unsigned int i;
17411 ULONG refcount;
17412 D3DCAPS9 caps;
17413 SHORT *texel;
17414 DWORD color;
17415 HWND window;
17416 HRESULT hr;
17418 static const struct
17420 struct vec3 position;
17421 struct vec3 texcrd;
17423 quads[] =
17425 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
17426 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
17427 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
17428 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
17430 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
17431 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
17432 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
17433 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
17435 static const DWORD shader_code[] =
17437 0xffff0101, /* ps_1_1 */
17438 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, */
17439 0x3f000000, 0x3f000000, /* 0.5, 0.5 */
17440 0x00000042, 0xb00f0000, /* tex t0 */
17441 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
17442 0x0000ffff /* end */
17445 window = create_window();
17446 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17447 ok(!!d3d, "Failed to create a D3D object.\n");
17448 if (!(device = create_device(d3d, window, window, TRUE)))
17450 skip("Failed to create a D3D device, skipping tests.\n");
17451 goto done;
17454 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17455 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17456 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
17458 skip("No ps_1_1 support, skipping tests.\n");
17459 IDirect3DDevice9_Release(device);
17460 goto done;
17462 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17463 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_V16U16)))
17465 skip("Volume V16U16 textures are not supported, skipping test.\n");
17466 IDirect3DDevice9_Release(device);
17467 goto done;
17470 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
17471 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
17472 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
17473 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
17474 hr = IDirect3DDevice9_SetPixelShader(device, shader);
17475 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
17476 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
17477 ok(SUCCEEDED(hr), "Failed to set filter, hr %#x.\n", hr);
17479 for (i = 0; i < 2; i++)
17481 D3DPOOL pool;
17483 if (i)
17484 pool = D3DPOOL_SYSTEMMEM;
17485 else
17486 pool = D3DPOOL_MANAGED;
17488 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
17489 pool, &texture, NULL);
17490 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
17492 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
17493 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
17495 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 0 * box.SlicePitch);
17496 texel[0] = 32767;
17497 texel[1] = 32767;
17498 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 0 * box.SlicePitch);
17499 texel[0] = -32768;
17500 texel[1] = 0;
17501 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 1 * box.SlicePitch);
17502 texel[0] = -16384;
17503 texel[1] = 16384;
17504 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 1 * box.SlicePitch);
17505 texel[0] = 0;
17506 texel[1] = 0;
17508 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
17509 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
17511 if (i)
17513 IDirect3DVolumeTexture9 *texture2;
17515 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
17516 D3DPOOL_DEFAULT, &texture2, NULL);
17517 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
17519 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture,
17520 (IDirect3DBaseTexture9 *)texture2);
17521 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17523 IDirect3DVolumeTexture9_Release(texture);
17524 texture = texture2;
17527 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
17528 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17530 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
17531 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17532 hr = IDirect3DDevice9_BeginScene(device);
17533 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17534 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
17535 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17536 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
17537 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17538 hr = IDirect3DDevice9_EndScene(device);
17539 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17541 color = getPixelColor(device, 120, 160);
17542 ok (color_match(color, 0x000080ff, 2),
17543 "Expected color 0x000080ff, got 0x%08x, V16U16 input -32768, 0.\n", color);
17544 color = getPixelColor(device, 120, 400);
17545 ok (color_match(color, 0x00ffffff, 2),
17546 "Expected color 0x00ffffff, got 0x%08x, V16U16 input 32767, 32767.\n", color);
17547 color = getPixelColor(device, 360, 160);
17548 ok (color_match(color, 0x007f7fff, 2),
17549 "Expected color 0x007f7fff, got 0x%08x, V16U16 input 0, 0.\n", color);
17550 color = getPixelColor(device, 360, 400);
17551 ok (color_match(color, 0x0040c0ff, 2),
17552 "Expected color 0x0040c0ff, got 0x%08x, V16U16 input -16384, 16384.\n", color);
17554 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17555 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17557 IDirect3DVolumeTexture9_Release(texture);
17560 IDirect3DPixelShader9_Release(shader);
17561 refcount = IDirect3DDevice9_Release(device);
17562 ok(!refcount, "Device has %u references left.\n", refcount);
17563 done:
17564 IDirect3D9_Release(d3d);
17565 DestroyWindow(window);
17568 static void add_dirty_rect_test_draw(IDirect3DDevice9 *device)
17570 HRESULT hr;
17571 static const struct
17573 struct vec3 position;
17574 struct vec2 texcoord;
17576 quad[] =
17578 {{-1.0, -1.0, 0.0}, {0.0, 0.0}},
17579 {{-1.0, 1.0, 0.0}, {0.0, 1.0}},
17580 {{ 1.0, -1.0, 0.0}, {1.0, 0.0}},
17581 {{ 1.0, 1.0, 0.0}, {1.0, 1.0}},
17584 hr = IDirect3DDevice9_BeginScene(device);
17585 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17586 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad, sizeof(*quad));
17587 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17588 hr = IDirect3DDevice9_EndScene(device);
17589 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17592 static void add_dirty_rect_test(void)
17594 HRESULT hr;
17595 IDirect3DTexture9 *tex_dst1, *tex_dst2, *tex_src_red, *tex_src_green,
17596 *tex_managed, *tex_dynamic;
17597 IDirect3DSurface9 *surface_dst2, *surface_src_green, *surface_src_red,
17598 *surface_managed0, *surface_managed1, *surface_dynamic;
17599 IDirect3DDevice9 *device;
17600 IDirect3D9 *d3d;
17601 unsigned int i;
17602 ULONG refcount;
17603 DWORD *texel;
17604 HWND window;
17605 D3DLOCKED_RECT locked_rect;
17606 static const RECT part_rect = {96, 96, 160, 160};
17607 DWORD color;
17609 window = create_window();
17610 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17611 ok(!!d3d, "Failed to create a D3D object.\n");
17612 if (!(device = create_device(d3d, window, window, TRUE)))
17614 skip("Failed to create a D3D device, skipping tests.\n");
17615 IDirect3D9_Release(d3d);
17616 DestroyWindow(window);
17617 return;
17620 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17621 D3DPOOL_DEFAULT, &tex_dst1, NULL);
17622 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17623 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17624 D3DPOOL_DEFAULT, &tex_dst2, NULL);
17625 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17626 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17627 D3DPOOL_SYSTEMMEM, &tex_src_red, NULL);
17628 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17629 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17630 D3DPOOL_SYSTEMMEM, &tex_src_green, NULL);
17631 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17632 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 2, 0, D3DFMT_X8R8G8B8,
17633 D3DPOOL_MANAGED, &tex_managed, NULL);
17634 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17635 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, D3DUSAGE_DYNAMIC,
17636 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex_dynamic, NULL);
17637 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17639 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dst2, 0, &surface_dst2);
17640 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17641 hr = IDirect3DTexture9_GetSurfaceLevel(tex_src_green, 0, &surface_src_green);
17642 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17643 hr = IDirect3DTexture9_GetSurfaceLevel(tex_src_red, 0, &surface_src_red);
17644 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17645 hr = IDirect3DTexture9_GetSurfaceLevel(tex_managed, 0, &surface_managed0);
17646 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17647 hr = IDirect3DTexture9_GetSurfaceLevel(tex_managed, 1, &surface_managed1);
17648 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17649 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dynamic, 0, &surface_dynamic);
17650 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17652 fill_surface(surface_src_red, 0x00ff0000, 0);
17653 fill_surface(surface_src_green, 0x0000ff00, 0);
17655 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
17656 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
17657 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17658 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17659 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
17660 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17661 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
17662 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
17664 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17665 (IDirect3DBaseTexture9 *)tex_dst1);
17666 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17668 /* The second UpdateTexture call writing to tex_dst2 is ignored because tex_src_green is not dirty. */
17669 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_red,
17670 (IDirect3DBaseTexture9 *)tex_dst2);
17671 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17672 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17673 (IDirect3DBaseTexture9 *)tex_dst2);
17674 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17676 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst1);
17677 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17678 add_dirty_rect_test_draw(device);
17679 color = getPixelColor(device, 320, 240);
17680 ok(color_match(color, 0x0000ff00, 1),
17681 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17682 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17683 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17685 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst2);
17686 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17687 add_dirty_rect_test_draw(device);
17688 color = getPixelColor(device, 320, 240);
17689 todo_wine ok(color_match(color, 0x00ff0000, 1),
17690 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17691 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17692 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17694 /* AddDirtyRect on the destination is ignored. */
17695 hr = IDirect3DTexture9_AddDirtyRect(tex_dst2, &part_rect);
17696 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17697 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17698 (IDirect3DBaseTexture9 *)tex_dst2);
17699 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17700 add_dirty_rect_test_draw(device);
17701 color = getPixelColor(device, 320, 240);
17702 todo_wine ok(color_match(color, 0x00ff0000, 1),
17703 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17704 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17705 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17707 hr = IDirect3DTexture9_AddDirtyRect(tex_dst2, NULL);
17708 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17709 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17710 (IDirect3DBaseTexture9 *)tex_dst2);
17711 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17712 add_dirty_rect_test_draw(device);
17713 color = getPixelColor(device, 320, 240);
17714 todo_wine ok(color_match(color, 0x00ff0000, 1),
17715 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17716 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17717 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17719 /* AddDirtyRect on the source makes UpdateTexture work. Partial rectangle
17720 * tracking is supported. */
17721 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, &part_rect);
17722 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17723 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17724 (IDirect3DBaseTexture9 *)tex_dst2);
17725 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17726 add_dirty_rect_test_draw(device);
17727 color = getPixelColor(device, 320, 240);
17728 ok(color_match(color, 0x0000ff00, 1),
17729 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17730 color = getPixelColor(device, 1, 1);
17731 todo_wine ok(color_match(color, 0x00ff0000, 1),
17732 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17733 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17734 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17736 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, NULL);
17737 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17738 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17739 (IDirect3DBaseTexture9 *)tex_dst2);
17740 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17741 add_dirty_rect_test_draw(device);
17742 color = getPixelColor(device, 1, 1);
17743 ok(color_match(color, 0x0000ff00, 1),
17744 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17746 /* Locks with NO_DIRTY_UPDATE are ignored. */
17747 fill_surface(surface_src_green, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE);
17748 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17749 (IDirect3DBaseTexture9 *)tex_dst2);
17750 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17751 add_dirty_rect_test_draw(device);
17752 color = getPixelColor(device, 320, 240);
17753 todo_wine ok(color_match(color, 0x0000ff00, 1),
17754 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17755 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17756 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17758 /* Readonly maps write to D3DPOOL_SYSTEMMEM, but don't record a dirty rectangle. */
17759 fill_surface(surface_src_green, 0x000000ff, D3DLOCK_READONLY);
17760 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17761 (IDirect3DBaseTexture9 *)tex_dst2);
17762 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17763 add_dirty_rect_test_draw(device);
17764 color = getPixelColor(device, 320, 240);
17765 todo_wine ok(color_match(color, 0x0000ff00, 1),
17766 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17767 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17768 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17770 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, NULL);
17771 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17772 (IDirect3DBaseTexture9 *)tex_dst2);
17773 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17774 add_dirty_rect_test_draw(device);
17775 color = getPixelColor(device, 320, 240);
17776 ok(color_match(color, 0x000000ff, 1),
17777 "Expected color 0x000000ff, got 0x%08x.\n", color);
17778 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17779 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17781 /* Maps without either of these flags record a dirty rectangle. */
17782 fill_surface(surface_src_green, 0x00ffffff, 0);
17783 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17784 (IDirect3DBaseTexture9 *)tex_dst2);
17785 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17786 add_dirty_rect_test_draw(device);
17787 color = getPixelColor(device, 320, 240);
17788 ok(color_match(color, 0x00ffffff, 1),
17789 "Expected color 0x00ffffff, got 0x%08x.\n", color);
17790 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17791 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17793 /* Partial LockRect works just like a partial AddDirtyRect call. */
17794 hr = IDirect3DTexture9_LockRect(tex_src_green, 0, &locked_rect, &part_rect, 0);
17795 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17796 texel = locked_rect.pBits;
17797 for (i = 0; i < 64; i++)
17798 texel[i] = 0x00ff00ff;
17799 for (i = 1; i < 64; i++)
17800 memcpy((BYTE *)locked_rect.pBits + i * locked_rect.Pitch, locked_rect.pBits, locked_rect.Pitch);
17801 hr = IDirect3DTexture9_UnlockRect(tex_src_green, 0);
17802 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17803 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17804 (IDirect3DBaseTexture9 *)tex_dst2);
17805 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17806 add_dirty_rect_test_draw(device);
17807 color = getPixelColor(device, 320, 240);
17808 ok(color_match(color, 0x00ff00ff, 1),
17809 "Expected color 0x00ff00ff, got 0x%08x.\n", color);
17810 color = getPixelColor(device, 1, 1);
17811 ok(color_match(color, 0x00ffffff, 1),
17812 "Expected color 0x00ffffff, got 0x%08x.\n", color);
17813 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17814 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17816 fill_surface(surface_src_red, 0x00ff0000, 0);
17817 fill_surface(surface_src_green, 0x0000ff00, 0);
17819 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17820 (IDirect3DBaseTexture9 *)tex_dst1);
17821 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17822 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst1);
17823 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17824 add_dirty_rect_test_draw(device);
17825 color = getPixelColor(device, 320, 240);
17826 ok(color_match(color, 0x0000ff00, 1),
17827 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17828 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17829 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17831 /* UpdateSurface ignores the missing dirty marker. */
17832 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_red,
17833 (IDirect3DBaseTexture9 *)tex_dst2);
17834 hr = IDirect3DDevice9_UpdateSurface(device, surface_src_green, NULL, surface_dst2, NULL);
17835 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
17836 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst2);
17837 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17838 add_dirty_rect_test_draw(device);
17839 color = getPixelColor(device, 320, 240);
17840 ok(color_match(color, 0x0000ff00, 1),
17841 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17842 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17843 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17845 /* Tests with managed textures. */
17846 fill_surface(surface_managed0, 0x00ff0000, 0);
17847 fill_surface(surface_managed1, 0x00ff0000, 0);
17848 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_managed);
17849 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17850 add_dirty_rect_test_draw(device);
17851 color = getPixelColor(device, 320, 240);
17852 ok(color_match(color, 0x00ff0000, 1),
17853 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17854 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17855 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17856 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
17857 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
17858 add_dirty_rect_test_draw(device);
17859 color = getPixelColor(device, 320, 240);
17860 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
17861 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17862 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17864 /* Managed textures also honor D3DLOCK_NO_DIRTY_UPDATE. */
17865 fill_surface(surface_managed0, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE);
17866 fill_surface(surface_managed1, 0x000000ff, D3DLOCK_NO_DIRTY_UPDATE);
17867 add_dirty_rect_test_draw(device);
17868 color = getPixelColor(device, 320, 240);
17869 ok(color_match(color, 0x00ff0000, 1),
17870 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17871 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17872 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17873 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
17874 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
17875 add_dirty_rect_test_draw(device);
17876 color = getPixelColor(device, 320, 240);
17877 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
17878 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17879 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17881 /* AddDirtyRect uploads the new contents.
17882 * Side note, not tested in the test: Partial surface updates work, and two separate
17883 * dirty rectangles are tracked individually. Tested on Nvidia Kepler, other drivers
17884 * untested. */
17885 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
17886 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17887 add_dirty_rect_test_draw(device);
17888 color = getPixelColor(device, 320, 240);
17889 ok(color_match(color, 0x0000ff00, 1),
17890 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17891 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17892 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17893 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
17894 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
17895 add_dirty_rect_test_draw(device);
17896 color = getPixelColor(device, 320, 240);
17897 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
17898 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17899 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17901 /* So does EvictManagedResources. */
17902 fill_surface(surface_managed0, 0x00ffff00, D3DLOCK_NO_DIRTY_UPDATE);
17903 fill_surface(surface_managed1, 0x00ff00ff, D3DLOCK_NO_DIRTY_UPDATE);
17904 hr = IDirect3DDevice9_EvictManagedResources(device);
17905 ok(SUCCEEDED(hr), "Failed to evict managed resources, hr %#x.\n", hr);
17906 add_dirty_rect_test_draw(device);
17907 color = getPixelColor(device, 320, 240);
17908 ok(color_match(color, 0x00ff00ff, 1), "Got unexpected color 0x%08x.\n", color);
17909 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17910 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17911 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
17912 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
17913 add_dirty_rect_test_draw(device);
17914 color = getPixelColor(device, 320, 240);
17915 ok(color_match(color, 0x00ffff00, 1), "Got unexpected color 0x%08x.\n", color);
17916 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17917 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17919 /* Tests with dynamic textures */
17920 fill_surface(surface_dynamic, 0x0000ffff, 0);
17921 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dynamic);
17922 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17923 add_dirty_rect_test_draw(device);
17924 color = getPixelColor(device, 320, 240);
17925 ok(color_match(color, 0x0000ffff, 1),
17926 "Expected color 0x0000ffff, got 0x%08x.\n", color);
17927 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17928 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17930 /* Dynamic textures don't honor D3DLOCK_NO_DIRTY_UPDATE. */
17931 fill_surface(surface_dynamic, 0x00ffff00, D3DLOCK_NO_DIRTY_UPDATE);
17932 add_dirty_rect_test_draw(device);
17933 color = getPixelColor(device, 320, 240);
17934 ok(color_match(color, 0x00ffff00, 1),
17935 "Expected color 0x00ffff00, got 0x%08x.\n", color);
17936 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17937 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17939 /* AddDirtyRect on a locked texture is allowed. */
17940 hr = IDirect3DTexture9_LockRect(tex_src_red, 0, &locked_rect, NULL, 0);
17941 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17942 hr = IDirect3DTexture9_AddDirtyRect(tex_src_red, NULL);
17943 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17944 hr = IDirect3DTexture9_UnlockRect(tex_src_red, 0);
17945 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17947 /* Redundant AddDirtyRect calls are ok. */
17948 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
17949 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17950 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
17951 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17953 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
17954 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17955 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
17956 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17957 IDirect3DSurface9_Release(surface_dst2);
17958 IDirect3DSurface9_Release(surface_managed1);
17959 IDirect3DSurface9_Release(surface_managed0);
17960 IDirect3DSurface9_Release(surface_src_red);
17961 IDirect3DSurface9_Release(surface_src_green);
17962 IDirect3DSurface9_Release(surface_dynamic);
17963 IDirect3DTexture9_Release(tex_src_red);
17964 IDirect3DTexture9_Release(tex_src_green);
17965 IDirect3DTexture9_Release(tex_dst1);
17966 IDirect3DTexture9_Release(tex_dst2);
17967 IDirect3DTexture9_Release(tex_managed);
17968 IDirect3DTexture9_Release(tex_dynamic);
17969 refcount = IDirect3DDevice9_Release(device);
17970 ok(!refcount, "Device has %u references left.\n", refcount);
17971 IDirect3D9_Release(d3d);
17972 DestroyWindow(window);
17975 static void test_per_stage_constant(void)
17977 IDirect3DDevice9 *device;
17978 IDirect3D9 *d3d;
17979 D3DCOLOR color;
17980 ULONG refcount;
17981 D3DCAPS9 caps;
17982 HWND window;
17983 HRESULT hr;
17985 static const struct
17987 struct vec3 position;
17988 D3DCOLOR diffuse;
17990 quad[] =
17992 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
17993 {{-1.0f, 1.0f, 0.1f}, 0xffff0000},
17994 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
17995 {{ 1.0f, 1.0f, 0.1f}, 0xffff0000},
17998 window = create_window();
17999 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18000 ok(!!d3d, "Failed to create a D3D object.\n");
18001 if (!(device = create_device(d3d, window, window, TRUE)))
18003 skip("Failed to create a D3D device, skipping tests.\n");
18004 goto done;
18007 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18008 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18009 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_PERSTAGECONSTANT))
18011 skip("Per-stage constants not supported, skipping tests.\n");
18012 IDirect3DDevice9_Release(device);
18013 goto done;
18016 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
18017 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
18018 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
18019 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18020 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
18021 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18022 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
18023 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18024 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18025 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18027 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_CONSTANT, 0x80a1b2c3);
18028 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
18029 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT);
18030 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
18031 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
18032 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
18034 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
18035 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18037 hr = IDirect3DDevice9_BeginScene(device);
18038 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18039 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18040 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18041 hr = IDirect3DDevice9_EndScene(device);
18042 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18044 color = getPixelColor(device, 320, 240);
18045 ok(color_match(color, 0x00a1b2c3, 1), "Got unexpected color 0x%08x.\n", color);
18046 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18047 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18049 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT | D3DTA_COMPLEMENT);
18050 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
18052 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
18053 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18055 hr = IDirect3DDevice9_BeginScene(device);
18056 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18057 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18058 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18059 hr = IDirect3DDevice9_EndScene(device);
18060 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18062 color = getPixelColor(device, 320, 240);
18063 ok(color_match(color, 0x005e4d3c, 1), "Got unexpected color 0x%08x.\n", color);
18064 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18065 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18067 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT | D3DTA_ALPHAREPLICATE);
18068 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
18070 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
18071 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18073 hr = IDirect3DDevice9_BeginScene(device);
18074 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18075 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18076 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18077 hr = IDirect3DDevice9_EndScene(device);
18078 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18080 color = getPixelColor(device, 320, 240);
18081 ok(color_match(color, 0x00808080, 1), "Got unexpected color 0x%08x.\n", color);
18082 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18083 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18085 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_CONSTANT);
18086 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
18087 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
18088 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
18089 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CURRENT);
18090 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
18092 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
18093 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18095 hr = IDirect3DDevice9_BeginScene(device);
18096 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18097 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18098 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18099 hr = IDirect3DDevice9_EndScene(device);
18100 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18102 color = getPixelColor(device, 320, 240);
18103 ok(color_match(color, 0x0080007f, 1), "Got unexpected color 0x%08x.\n", color);
18104 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18105 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18107 refcount = IDirect3DDevice9_Release(device);
18108 ok(!refcount, "Device has %u references left.\n", refcount);
18109 done:
18110 IDirect3D9_Release(d3d);
18111 DestroyWindow(window);
18114 static void test_3dc_formats(void)
18116 static const char ati1n_data[] =
18118 /* A 4x4 texture with the color component at 50%. */
18119 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
18121 static const char ati2n_data[] =
18123 /* A 8x4 texture consisting of 2 4x4 blocks. The first block has 50% first color component,
18124 * 0% second component. Second block is the opposite. */
18125 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
18126 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
18128 static const struct
18130 struct vec3 position;
18131 struct vec2 texcoord;
18133 quads[] =
18135 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
18136 {{-1.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
18137 {{ 0.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
18138 {{ 0.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
18140 {{ 0.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
18141 {{ 0.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
18142 {{ 1.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
18143 {{ 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
18145 static const DWORD ati1n_fourcc = MAKEFOURCC('A','T','I','1');
18146 static const DWORD ati2n_fourcc = MAKEFOURCC('A','T','I','2');
18147 static const struct
18149 struct vec2 position;
18150 D3DCOLOR amd_r500;
18151 D3DCOLOR amd_r600;
18152 D3DCOLOR nvidia_old;
18153 D3DCOLOR nvidia_new;
18155 expected_colors[] =
18157 {{ 80, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
18158 {{240, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
18159 {{400, 240}, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff},
18160 {{560, 240}, 0x007f00ff, 0x007f00ff, 0x007f00ff, 0x007f00ff},
18162 IDirect3D9 *d3d;
18163 IDirect3DDevice9 *device;
18164 IDirect3DTexture9 *ati1n_texture, *ati2n_texture;
18165 D3DCAPS9 caps;
18166 D3DLOCKED_RECT rect;
18167 D3DCOLOR color;
18168 ULONG refcount;
18169 HWND window;
18170 HRESULT hr;
18171 unsigned int i;
18173 window = create_window();
18174 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18175 ok(!!d3d, "Failed to create a D3D object.\n");
18176 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
18177 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati1n_fourcc)))
18179 skip("ATI1N textures are not supported, skipping test.\n");
18180 goto done;
18182 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
18183 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati2n_fourcc)))
18185 skip("ATI2N textures are not supported, skipping test.\n");
18186 goto done;
18188 if (!(device = create_device(d3d, window, window, TRUE)))
18190 skip("Failed to create a D3D device, skipping tests.\n");
18191 goto done;
18193 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18194 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18195 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
18197 skip("D3DTA_TEMP not supported, skipping tests.\n");
18198 IDirect3DDevice9_Release(device);
18199 goto done;
18202 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, ati1n_fourcc,
18203 D3DPOOL_MANAGED, &ati1n_texture, NULL);
18204 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
18206 hr = IDirect3DTexture9_LockRect(ati1n_texture, 0, &rect, NULL, 0);
18207 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
18208 memcpy(rect.pBits, ati1n_data, sizeof(ati1n_data));
18209 hr = IDirect3DTexture9_UnlockRect(ati1n_texture, 0);
18210 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
18212 hr = IDirect3DDevice9_CreateTexture(device, 8, 4, 1, 0, ati2n_fourcc,
18213 D3DPOOL_MANAGED, &ati2n_texture, NULL);
18214 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
18216 hr = IDirect3DTexture9_LockRect(ati2n_texture, 0, &rect, NULL, 0);
18217 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
18218 memcpy(rect.pBits, ati2n_data, sizeof(ati2n_data));
18219 hr = IDirect3DTexture9_UnlockRect(ati2n_texture, 0);
18220 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
18222 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0));
18223 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
18224 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
18225 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
18226 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
18227 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
18228 /* The temporary register is initialized to 0. */
18229 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TEMP);
18230 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
18231 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
18232 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#x.\n", hr);
18233 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
18234 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#x.\n", hr);
18235 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
18236 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
18237 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
18238 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
18240 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
18241 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18242 hr = IDirect3DDevice9_BeginScene(device);
18243 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18244 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)ati1n_texture);
18245 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
18246 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
18247 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18248 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)ati2n_texture);
18249 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
18250 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
18251 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18252 hr = IDirect3DDevice9_EndScene(device);
18253 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18255 for (i = 0; i < 4; ++i)
18257 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
18258 ok (color_match(color, expected_colors[i].amd_r500, 1)
18259 || color_match(color, expected_colors[i].amd_r600, 1)
18260 || color_match(color, expected_colors[i].nvidia_old, 1)
18261 || color_match(color, expected_colors[i].nvidia_new, 1),
18262 "Got unexpected color 0x%08x, case %u.\n", color, i);
18265 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18266 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18267 IDirect3DTexture9_Release(ati2n_texture);
18268 IDirect3DTexture9_Release(ati1n_texture);
18269 refcount = IDirect3DDevice9_Release(device);
18270 ok(!refcount, "Device has %u references left.\n", refcount);
18272 done:
18273 IDirect3D9_Release(d3d);
18274 DestroyWindow(window);
18277 static void test_fog_interpolation(void)
18279 HRESULT hr;
18280 IDirect3DDevice9 *device;
18281 IDirect3D9 *d3d;
18282 ULONG refcount;
18283 HWND window;
18284 D3DCOLOR color;
18285 static const struct
18287 struct vec3 position;
18288 D3DCOLOR diffuse;
18289 D3DCOLOR specular;
18291 quad[] =
18293 {{-1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff000000},
18294 {{-1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff000000},
18295 {{ 1.0f, -1.0f, 1.0f}, 0xffff0000, 0x00000000},
18296 {{ 1.0f, 1.0f, 1.0f}, 0xffff0000, 0x00000000},
18298 union
18300 DWORD d;
18301 float f;
18302 } conv;
18303 unsigned int i;
18304 static const struct
18306 D3DFOGMODE vfog, tfog;
18307 D3DSHADEMODE shade;
18308 D3DCOLOR middle_color;
18309 BOOL todo;
18311 tests[] =
18313 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, FALSE},
18314 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, FALSE},
18315 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, TRUE},
18316 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, TRUE},
18317 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
18318 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
18319 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
18320 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
18322 static const D3DMATRIX ident_mat =
18324 1.0f, 0.0f, 0.0f, 0.0f,
18325 0.0f, 1.0f, 0.0f, 0.0f,
18326 0.0f, 0.0f, 1.0f, 0.0f,
18327 0.0f, 0.0f, 0.0f, 1.0f
18328 }}};
18329 D3DCAPS9 caps;
18331 window = create_window();
18332 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18333 ok(!!d3d, "Failed to create a D3D object.\n");
18335 if (!(device = create_device(d3d, window, window, TRUE)))
18337 skip("Failed to create a D3D device, skipping tests.\n");
18338 IDirect3D9_Release(d3d);
18339 DestroyWindow(window);
18340 return;
18343 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18344 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18345 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
18346 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
18348 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
18349 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
18350 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18351 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18352 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
18353 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18354 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
18355 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18356 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
18357 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18358 conv.f = 5.0;
18359 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGDENSITY, conv.d);
18360 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18362 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
18363 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
18364 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
18365 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
18366 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x000000ff);
18367 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18369 /* Some of the tests seem to depend on the projection matrix explicitly
18370 * being set to an identity matrix, even though that's the default.
18371 * (AMD Radeon X1600, AMD Radeon HD 6310, Windows 7). Without this,
18372 * the drivers seem to use a static z = 1.0 input for the fog equation.
18373 * The input value is independent of the actual z and w component of
18374 * the vertex position. */
18375 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
18376 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
18378 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
18380 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
18381 continue;
18383 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00808080, 0.0f, 0);
18384 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18386 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shade);
18387 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18388 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
18389 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18390 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
18391 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18392 hr = IDirect3DDevice9_BeginScene(device);
18393 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18394 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18395 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18396 hr = IDirect3DDevice9_EndScene(device);
18397 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18399 color = getPixelColor(device, 0, 240);
18400 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
18401 color = getPixelColor(device, 320, 240);
18402 todo_wine_if (tests[i].todo)
18403 ok(color_match(color, tests[i].middle_color, 2),
18404 "Got unexpected color 0x%08x, case %u.\n", color, i);
18405 color = getPixelColor(device, 639, 240);
18406 ok(color_match(color, 0x0000fd02, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
18407 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18408 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18411 refcount = IDirect3DDevice9_Release(device);
18412 ok(!refcount, "Device has %u references left.\n", refcount);
18413 IDirect3D9_Release(d3d);
18414 DestroyWindow(window);
18417 static void test_negative_fixedfunction_fog(void)
18419 HRESULT hr;
18420 IDirect3DDevice9 *device;
18421 IDirect3D9 *d3d;
18422 ULONG refcount;
18423 HWND window;
18424 D3DCOLOR color;
18425 static const struct
18427 struct vec3 position;
18428 D3DCOLOR diffuse;
18430 quad[] =
18432 {{-1.0f, -1.0f, -0.5f}, 0xffff0000},
18433 {{-1.0f, 1.0f, -0.5f}, 0xffff0000},
18434 {{ 1.0f, -1.0f, -0.5f}, 0xffff0000},
18435 {{ 1.0f, 1.0f, -0.5f}, 0xffff0000},
18437 static const struct
18439 struct vec4 position;
18440 D3DCOLOR diffuse;
18442 tquad[] =
18444 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
18445 {{640.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
18446 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
18447 {{640.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
18449 unsigned int i;
18450 static const D3DMATRIX zero =
18452 1.0f, 0.0f, 0.0f, 0.0f,
18453 0.0f, 1.0f, 0.0f, 0.0f,
18454 0.0f, 0.0f, 0.0f, 0.0f,
18455 0.0f, 0.0f, 0.0f, 1.0f
18456 }}};
18457 /* Needed to make AMD drivers happy. Yeah, it is not supposed to
18458 * have an effect on RHW draws. */
18459 static const D3DMATRIX identity =
18461 1.0f, 0.0f, 0.0f, 0.0f,
18462 0.0f, 1.0f, 0.0f, 0.0f,
18463 0.0f, 0.0f, 1.0f, 0.0f,
18464 0.0f, 0.0f, 0.0f, 1.0f
18465 }}};
18466 static const struct
18468 DWORD pos_type;
18469 const void *quad;
18470 size_t stride;
18471 const D3DMATRIX *matrix;
18472 union
18474 float f;
18475 DWORD d;
18476 } start, end;
18477 D3DFOGMODE vfog, tfog;
18478 DWORD color, color_broken, color_broken2;
18480 tests[] =
18482 /* Run the XYZRHW tests first. Depth clamping is broken after RHW draws on the testbot.
18484 * Geforce8+ GPUs on Windows abs() table fog, everything else does not. */
18485 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, { 0.0f}, {1.0f},
18486 D3DFOG_NONE, D3DFOG_LINEAR, 0x00ff0000, 0x00808000, 0x00808000},
18487 /* r200 GPUs and presumably all d3d8 and older HW clamp the fog
18488 * parameters to 0.0 and 1.0 in the table fog case. */
18489 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, {-1.0f}, {0.0f},
18490 D3DFOG_NONE, D3DFOG_LINEAR, 0x00808000, 0x00ff0000, 0x0000ff00},
18491 /* test_fog_interpolation shows that vertex fog evaluates the fog
18492 * equation in the vertex pipeline. Start = -1.0 && end = 0.0 shows
18493 * that the abs happens before the fog equation is evaluated.
18495 * Vertex fog abs() behavior is the same on all GPUs. */
18496 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
18497 D3DFOG_LINEAR, D3DFOG_NONE, 0x00808000, 0x00808000, 0x00808000},
18498 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, {-1.0f}, {0.0f},
18499 D3DFOG_LINEAR, D3DFOG_NONE, 0x0000ff00, 0x0000ff00, 0x0000ff00},
18500 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
18501 D3DFOG_EXP, D3DFOG_NONE, 0x009b6400, 0x009b6400, 0x009b6400},
18503 D3DCAPS9 caps;
18505 window = create_window();
18506 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18507 ok(!!d3d, "Failed to create a D3D object.\n");
18509 if (!(device = create_device(d3d, window, window, TRUE)))
18511 skip("Failed to create a D3D device, skipping tests.\n");
18512 IDirect3D9_Release(d3d);
18513 DestroyWindow(window);
18514 return;
18517 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18518 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18519 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
18520 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests.\n");
18522 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18523 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18524 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
18525 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18526 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
18527 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18528 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
18529 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18530 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
18531 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
18533 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
18535 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
18536 continue;
18538 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
18539 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18541 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, tests[i].matrix);
18542 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
18543 hr = IDirect3DDevice9_SetFVF(device, tests[i].pos_type | D3DFVF_DIFFUSE);
18544 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
18545 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, tests[i].start.d);
18546 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18547 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, tests[i].end.d);
18548 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18549 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
18550 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18551 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
18552 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18554 hr = IDirect3DDevice9_BeginScene(device);
18555 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18556 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tests[i].quad, tests[i].stride);
18557 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18558 hr = IDirect3DDevice9_EndScene(device);
18559 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18561 color = getPixelColor(device, 320, 240);
18562 ok(color_match(color, tests[i].color, 2) || broken(color_match(color, tests[i].color_broken, 2))
18563 || broken(color_match(color, tests[i].color_broken2, 2)),
18564 "Got unexpected color 0x%08x, case %u.\n", color, i);
18565 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18566 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18569 refcount = IDirect3DDevice9_Release(device);
18570 ok(!refcount, "Device has %u references left.\n", refcount);
18571 IDirect3D9_Release(d3d);
18572 DestroyWindow(window);
18575 static void test_position_index(void)
18577 static const D3DVERTEXELEMENT9 decl_elements[] =
18579 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
18580 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 1},
18581 D3DDECL_END()
18583 /* Declaring (and using) a position1 output semantic in a VS fails at draw time on AMD
18584 * but works on Nvidia.
18585 * MSDN is not consistent on this point. */
18586 static const DWORD vs_code[] =
18588 0xfffe0300, /* vs_3_0 */
18589 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
18590 0x0200001f, 0x80010000, 0x900f0001, /* dcl_position1 v1 */
18591 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position0 o0 */
18592 0x0200001f, 0x80010000, 0xe00f0001, /* dcl_position1 o1 */
18593 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
18594 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
18595 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
18596 0x02000001, 0xe00f0002, 0x90e40001, /* mov o2, v1 */
18597 0x0000ffff /* end */
18599 static const DWORD vs_code_2[] =
18601 0xfffe0300, /* vs_3_0 */
18602 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
18603 0x0200001f, 0x80010000, 0x900f0001, /* dcl_position1 v1 */
18604 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position0 o0 */
18605 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
18606 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
18607 0x02000001, 0xe00f0002, 0x90e40001, /* mov o2, v1 */
18608 0x0000ffff /* end */
18610 static const DWORD ps_code[] =
18612 0xffff0300, /* ps_3_0 */
18613 0x0200001f, 0x80010000, 0x900f0000, /* dcl_position1 v0 */
18614 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
18615 0x0000ffff /* end */
18617 static const DWORD ps_code_2[] =
18619 0xffff0300, /* ps_3_0 */
18620 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
18621 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
18622 0x0000ffff /* end */
18624 /* This one is considered invalid by the native shader assembler. */
18625 static const DWORD ps_code_bad[] =
18627 0xffff0300, /* ps_3_0 */
18628 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
18629 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
18630 0x0000ffff /* end */
18632 static const struct
18634 struct vec3 position;
18635 struct vec3 position1;
18637 quad[] =
18639 {{-1.0f, -1.0f, 0.5f}, {1.0f, 0.0f, 0.0f}},
18640 {{-1.0f, 1.0f, 0.5f}, {1.0f, 0.0f, 0.0f}},
18641 {{ 1.0f, -1.0f, 0.5f}, {0.0f, 1.0f, 0.0f}},
18642 {{ 1.0f, 1.0f, 0.5f}, {0.0f, 1.0f, 0.0f}},
18644 static const struct
18646 struct vec2 position;
18647 D3DCOLOR expected_color;
18648 D3DCOLOR broken_color;
18650 expected_colors[] =
18652 {{ 80, 240}, 0x00df2000, 0x00ff00ff},
18653 {{240, 240}, 0x009f6000, 0x00ff00ff},
18654 {{400, 240}, 0x00609f00, 0x00ff00ff},
18655 {{560, 240}, 0x0020df00, 0x00ff00ff},
18657 IDirect3D9 *d3d;
18658 IDirect3DDevice9 *device;
18659 IDirect3DVertexDeclaration9 *vertex_declaration;
18660 IDirect3DVertexShader9 *vs, *vs2;
18661 IDirect3DPixelShader9 *ps, *ps2;
18662 D3DCAPS9 caps;
18663 D3DCOLOR color;
18664 ULONG refcount;
18665 HWND window;
18666 HRESULT hr;
18667 unsigned int i;
18669 window = create_window();
18670 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18671 ok(!!d3d, "Failed to create a D3D object.\n");
18672 if (!(device = create_device(d3d, window, window, TRUE)))
18674 skip("Failed to create a D3D device, skipping tests.\n");
18675 goto done;
18678 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18679 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18680 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0)
18681 || caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
18683 skip("Shader model 3.0 unsupported, skipping tests.\n");
18684 IDirect3DDevice9_Release(device);
18685 goto done;
18688 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
18689 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed, hr %#x\n", hr);
18691 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
18692 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x\n", hr);
18694 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
18695 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
18696 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code_2, &vs2);
18697 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
18699 hr = IDirect3DDevice9_SetVertexShader(device, vs);
18700 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
18702 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_bad, &ps);
18703 ok(hr == D3DERR_INVALIDCALL, "CreatePixelShader returned hr %#x.\n", hr);
18705 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
18706 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
18707 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_2, &ps2);
18708 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
18710 hr = IDirect3DDevice9_SetPixelShader(device, ps);
18711 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18713 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
18714 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18715 hr = IDirect3DDevice9_BeginScene(device);
18716 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18717 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18718 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18719 hr = IDirect3DDevice9_EndScene(device);
18720 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18722 for (i = 0; i < sizeof(expected_colors) / sizeof(expected_colors[0]); ++i)
18724 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
18725 ok (color_match(color, expected_colors[i].expected_color, 1)
18726 || broken(color_match(color, expected_colors[i].broken_color, 1)),
18727 "Got unexpected color 0x%08x, case %u.\n", color, i);
18730 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
18731 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18733 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
18734 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18735 hr = IDirect3DDevice9_BeginScene(device);
18736 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18737 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18738 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18739 hr = IDirect3DDevice9_EndScene(device);
18740 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18742 for (i = 0; i < sizeof(expected_colors) / sizeof(expected_colors[0]); ++i)
18744 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
18745 ok (color_match(color, expected_colors[i].expected_color, 1)
18746 || broken(color_match(color, expected_colors[i].broken_color, 1)),
18747 "Got unexpected color 0x%08x, case %u.\n", color, i);
18750 hr = IDirect3DDevice9_SetVertexShader(device, vs2);
18751 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
18753 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
18754 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18755 hr = IDirect3DDevice9_BeginScene(device);
18756 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18757 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18758 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18759 hr = IDirect3DDevice9_EndScene(device);
18760 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18762 for (i = 0; i < sizeof(expected_colors) / sizeof(expected_colors[0]); ++i)
18764 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
18765 ok (color_match(color, expected_colors[i].expected_color, 1),
18766 "Got unexpected color 0x%08x, case %u.\n", color, i);
18769 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18770 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18772 IDirect3DPixelShader9_Release(ps2);
18773 IDirect3DPixelShader9_Release(ps);
18774 IDirect3DVertexShader9_Release(vs2);
18775 IDirect3DVertexShader9_Release(vs);
18776 IDirect3DVertexDeclaration9_Release(vertex_declaration);
18777 refcount = IDirect3DDevice9_Release(device);
18778 ok(!refcount, "Device has %u references left.\n", refcount);
18780 done:
18781 IDirect3D9_Release(d3d);
18782 DestroyWindow(window);
18785 static void test_table_fog_zw(void)
18787 HRESULT hr;
18788 IDirect3DDevice9 *device;
18789 IDirect3D9 *d3d;
18790 ULONG refcount;
18791 HWND window;
18792 D3DCOLOR color;
18793 D3DCAPS9 caps;
18794 static struct
18796 struct vec4 position;
18797 D3DCOLOR diffuse;
18799 quad[] =
18801 {{ 0.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
18802 {{640.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
18803 {{ 0.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
18804 {{640.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
18806 static const D3DMATRIX identity =
18808 1.0f, 0.0f, 0.0f, 0.0f,
18809 0.0f, 1.0f, 0.0f, 0.0f,
18810 0.0f, 0.0f, 1.0f, 0.0f,
18811 0.0f, 0.0f, 0.0f, 1.0f
18812 }}};
18813 static const struct
18815 float z, w;
18816 D3DZBUFFERTYPE z_test;
18817 D3DCOLOR color;
18819 tests[] =
18821 {0.7f, 0.0f, D3DZB_TRUE, 0x004cb200},
18822 {0.7f, 0.0f, D3DZB_FALSE, 0x004cb200},
18823 {0.7f, 0.3f, D3DZB_TRUE, 0x004cb200},
18824 {0.7f, 0.3f, D3DZB_FALSE, 0x004cb200},
18825 {0.7f, 3.0f, D3DZB_TRUE, 0x004cb200},
18826 {0.7f, 3.0f, D3DZB_FALSE, 0x004cb200},
18827 {0.3f, 0.0f, D3DZB_TRUE, 0x00b24c00},
18828 {0.3f, 0.0f, D3DZB_FALSE, 0x00b24c00},
18830 unsigned int i;
18832 window = create_window();
18833 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18834 ok(!!d3d, "Failed to create a D3D object.\n");
18836 if (!(device = create_device(d3d, window, window, TRUE)))
18838 skip("Failed to create a D3D device, skipping tests.\n");
18839 IDirect3D9_Release(d3d);
18840 DestroyWindow(window);
18841 return;
18844 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18845 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18846 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
18848 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping POSITIONT table fog test.\n");
18849 goto done;
18852 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18853 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18854 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
18855 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18856 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
18857 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18858 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
18859 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
18860 /* Work around an AMD Windows driver bug. Needs a proj matrix applied redundantly. */
18861 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
18862 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
18863 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
18864 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18865 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
18866 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
18868 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
18870 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
18871 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18873 quad[0].position.z = tests[i].z;
18874 quad[1].position.z = tests[i].z;
18875 quad[2].position.z = tests[i].z;
18876 quad[3].position.z = tests[i].z;
18877 quad[0].position.w = tests[i].w;
18878 quad[1].position.w = tests[i].w;
18879 quad[2].position.w = tests[i].w;
18880 quad[3].position.w = tests[i].w;
18881 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, tests[i].z_test);
18882 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18884 hr = IDirect3DDevice9_BeginScene(device);
18885 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18886 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
18887 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18888 hr = IDirect3DDevice9_EndScene(device);
18889 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18891 color = getPixelColor(device, 320, 240);
18892 ok(color_match(color, tests[i].color, 2),
18893 "Got unexpected color 0x%08x, expected 0x%08x, case %u.\n", color, tests[i].color, i);
18894 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18895 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18898 done:
18899 refcount = IDirect3DDevice9_Release(device);
18900 ok(!refcount, "Device has %u references left.\n", refcount);
18901 IDirect3D9_Release(d3d);
18902 DestroyWindow(window);
18905 static void test_signed_formats(void)
18907 IDirect3DDevice9 *device;
18908 HWND window;
18909 HRESULT hr;
18910 unsigned int i, j, x, y;
18911 IDirect3DTexture9 *texture, *texture_sysmem;
18912 IDirect3DSurface9 *src_surface, *dst_surface;
18913 D3DLOCKED_RECT locked_rect;
18914 IDirect3DPixelShader9 *shader, *shader_alpha;
18915 IDirect3D9 *d3d;
18916 D3DCOLOR color;
18917 D3DCAPS9 caps;
18918 ULONG refcount;
18920 /* The input data was designed for D3DFMT_L6V5U5 and then transferred
18921 * to the other formats because L6V5U5 is the lowest precision format.
18922 * It tests the extreme values -1.0 (-16) and 1.0 (15) for U/V and
18923 * 0.0 (0) and 1.0 (63) for L, the neutral point 0 as well as -1 and 1.
18924 * Some other intermediate values are tested too. The input value -15
18925 * (min + 1) is tested as well. Unlike what OpenGL 4.4 says in section
18926 * 2.3.4.1, this value does not represent -1.0. In the interest of re-
18927 * using the expected output data the 8 bit and 16 bit values in V8U8
18928 * and V16U16 match (post-normalization) the 5 bit input values. Thus
18929 * -1, 1 and -127 are not tested in V8U8.
18931 * 8 bit specific values like -127 are tested in the Q channel of
18932 * D3DFMT_Q8W8V8U8. Here d3d seems to follow the rules from the GL
18933 * spec. AMD's r200 is broken though and returns a value < -1.0 for
18934 * -128. The difference between using -127 or -128 as the lowest
18935 * possible value gets lost in the slop of 1 though. */
18936 static const USHORT content_v8u8[4][4] =
18938 {0x0000, 0x7f7f, 0x8880, 0x0000},
18939 {0x0080, 0x8000, 0x7f00, 0x007f},
18940 {0x193b, 0xe8c8, 0x0808, 0xf8f8},
18941 {0x4444, 0xc0c0, 0xa066, 0x22e0},
18943 static const DWORD content_v16u16[4][4] =
18945 {0x00000000, 0x7fff7fff, 0x88008000, 0x00000000},
18946 {0x00008000, 0x80000000, 0x7fff0000, 0x00007fff},
18947 {0x19993bbb, 0xe800c800, 0x08880888, 0xf800f800},
18948 {0x44444444, 0xc000c000, 0xa0006666, 0x2222e000},
18950 static const DWORD content_q8w8v8u8[4][4] =
18952 {0x00000000, 0xff7f7f7f, 0x7f008880, 0x817f0000},
18953 {0x10000080, 0x20008000, 0x30007f00, 0x4000007f},
18954 {0x5020193b, 0x6028e8c8, 0x70020808, 0x807ff8f8},
18955 {0x90414444, 0xa000c0c0, 0x8261a066, 0x834922e0},
18957 static const DWORD content_x8l8v8u8[4][4] =
18959 {0x00000000, 0x00ff7f7f, 0x00008880, 0x00ff0000},
18960 {0x00000080, 0x00008000, 0x00007f00, 0x0000007f},
18961 {0x0041193b, 0x0051e8c8, 0x00040808, 0x00fff8f8},
18962 {0x00824444, 0x0000c0c0, 0x00c2a066, 0x009222e0},
18964 /* D3DFMT_L6V5U5 has poor precision on some GPUs. On a GeForce 7 the highest V and U value (15)
18965 * results in the output color 0xfb, which is 4 steps away from the correct value 0xff. It is
18966 * not the ~0xf0 you'd get if you blindly left-shifted the 5 bit value to form an 8 bit value
18967 * though.
18969 * There may also be an off-by-one bug involved: The value -7 should result in the output 0x47,
18970 * but ends up as 0x4d. Likewise, -3 becomes 0x6e instead of 0x67. Those values are close to
18971 * the proper results of -6 and -2.
18973 * On Wine the emulation with unsigned R5G6B5 has poor precision, e.g. the signed 0 becomes 16,
18974 * and ((16 / 31) - 0.5) * 2.0 is 0.032 instead of 0.000. The final output result we read back
18975 * is 0x84 instead of 0x80. */
18976 static const USHORT content_l6v5u5[4][4] =
18978 {0x0000, 0xfdef, 0x0230, 0xfc00},
18979 {0x0010, 0x0200, 0x01e0, 0x000f},
18980 {0x4067, 0x53b9, 0x0421, 0xffff},
18981 {0x8108, 0x0318, 0xc28c, 0x909c},
18983 static const struct
18985 D3DFORMAT format;
18986 const char *name;
18987 const void *content;
18988 SIZE_T pixel_size;
18989 BOOL blue, alpha;
18990 unsigned int slop, slop_broken, alpha_broken;
18992 formats[] =
18994 {D3DFMT_V8U8, "D3DFMT_V8U8", content_v8u8, sizeof(WORD), FALSE, FALSE, 1, 0, FALSE},
18995 {D3DFMT_V16U16, "D3DFMT_V16U16", content_v16u16, sizeof(DWORD), FALSE, FALSE, 1, 0, FALSE},
18996 {D3DFMT_Q8W8V8U8, "D3DFMT_Q8W8V8U8", content_q8w8v8u8, sizeof(DWORD), TRUE, TRUE, 1, 0, TRUE },
18997 {D3DFMT_X8L8V8U8, "D3DFMT_X8L8V8U8", content_x8l8v8u8, sizeof(DWORD), TRUE, FALSE, 1, 0, FALSE},
18998 {D3DFMT_L6V5U5, "D3DFMT_L6V5U5", content_l6v5u5, sizeof(WORD), TRUE, FALSE, 4, 7, FALSE},
19000 static const struct
19002 D3DPOOL pool;
19003 UINT width;
19004 RECT src_rect;
19005 POINT dst_point;
19007 tests[] =
19009 {D3DPOOL_SYSTEMMEM, 4, {1, 1, 2, 3}, {2, 0}},
19010 {D3DPOOL_SYSTEMMEM, 1, {0, 1, 1, 3}, {0, 0}},
19011 {D3DPOOL_MANAGED, 4, {1, 1, 2, 3}, {2, 0}},
19012 {D3DPOOL_MANAGED, 1, {0, 1, 1, 3}, {0, 0}},
19014 static const DWORD shader_code[] =
19016 0xffff0101, /* ps_1_1 */
19017 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0,5, 0,5 */
19018 0x00000042, 0xb00f0000, /* tex t0 */
19019 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
19020 0x0000ffff /* end */
19022 static const DWORD shader_code_alpha[] =
19024 /* The idea of this shader is to replicate the alpha value in .rg, and set
19025 * blue to 1.0 iff the alpha value is < -1.0 and 0.0 otherwise. */
19026 0xffff0101, /* ps_1_1 */
19027 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
19028 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
19029 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
19030 0x00000042, 0xb00f0000, /* tex t0 */
19031 0x00000004, 0x80070000, 0xb0ff0000, 0xa0e40000, 0xa0e40000, /* mad r0.rgb, t0.a, c0, c0 */
19032 0x00000003, 0x80080000, 0xb1ff0000, 0xa0e40000, /* sub r0.a, -t0.a, c0 */
19033 0x00000050, 0x80080000, 0x80ff0000, 0xa0ff0001, 0xa0ff0002, /* cnd r0.a, r0.a, c1.a, c2.a */
19034 0x00000005, 0x80070001, 0xa0e40001, 0x80e40000, /* mul r1.rgb, c1, r0 */
19035 0x00000004, 0x80070000, 0x80ff0000, 0xa0e40002, 0x80e40001, /* mad r0.rgb, r0.a, c2, r1 */
19036 0x0000ffff /* end */
19038 static const struct
19040 struct vec3 position;
19041 struct vec2 texcrd;
19043 quad[] =
19045 /* Flip the y coordinate to make the input and
19046 * output arrays easier to compare. */
19047 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 1.0f}},
19048 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 0.0f}},
19049 {{ 1.0f, -1.0f, 0.0f}, { 1.0f, 1.0f}},
19050 {{ 1.0f, 1.0f, 0.0f}, { 1.0f, 0.0f}},
19052 static const D3DCOLOR expected_alpha[4][4] =
19054 {0x00808000, 0x007f7f00, 0x00ffff00, 0x00000000},
19055 {0x00909000, 0x00a0a000, 0x00b0b000, 0x00c0c000},
19056 {0x00d0d000, 0x00e0e000, 0x00f0f000, 0x00000000},
19057 {0x00101000, 0x00202000, 0x00010100, 0x00020200},
19059 static const BOOL alpha_broken[4][4] =
19061 {FALSE, FALSE, FALSE, FALSE},
19062 {FALSE, FALSE, FALSE, FALSE},
19063 {FALSE, FALSE, FALSE, TRUE },
19064 {FALSE, FALSE, FALSE, FALSE},
19066 static const D3DCOLOR expected_colors[4][4] =
19068 {0x00808080, 0x00fefeff, 0x00010780, 0x008080ff},
19069 {0x00018080, 0x00800180, 0x0080fe80, 0x00fe8080},
19070 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
19071 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
19073 static const D3DCOLOR expected_colors2[4][4] =
19075 {0x00808080, 0x00fefeff, 0x00800180, 0x008080ff},
19076 {0x00018080, 0x00800180, 0x004767a8, 0x00fe8080},
19077 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
19078 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
19080 static const D3DCOLOR expected_colors3[4] =
19082 0x00018080,
19083 0x00ba98a0,
19084 0x00ba98a0,
19085 0x00c3c3c0,
19087 D3DCOLOR expected_color;
19089 window = create_window();
19090 d3d = Direct3DCreate9(D3D_SDK_VERSION);
19091 ok(!!d3d, "Failed to create a D3D object.\n");
19093 if (!(device = create_device(d3d, window, window, TRUE)))
19095 skip("Failed to create a D3D device, skipping tests.\n");
19096 IDirect3D9_Release(d3d);
19097 DestroyWindow(window);
19098 return;
19101 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
19102 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
19104 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
19106 skip("Pixel shaders not supported, skipping converted format test.\n");
19107 goto done;
19110 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
19111 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19112 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
19113 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
19114 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
19115 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
19116 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_alpha, &shader_alpha);
19117 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
19119 for (i = 0; i < sizeof(formats) / sizeof(*formats); i++)
19121 hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
19122 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, formats[i].format);
19123 if (FAILED(hr))
19125 skip("Format %s not supported, skipping.\n", formats[i].name);
19126 continue;
19129 for (j = 0; j < sizeof(tests) / sizeof(*tests); j++)
19131 texture_sysmem = NULL;
19132 hr = IDirect3DDevice9_CreateTexture(device, tests[j].width, 4, 1, 0,
19133 formats[i].format, tests[j].pool, &texture, NULL);
19134 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
19136 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
19137 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
19138 for (y = 0; y < 4; y++)
19140 memcpy((char *)locked_rect.pBits + y * locked_rect.Pitch,
19141 (char *)formats[i].content + y * 4 * formats[i].pixel_size,
19142 tests[j].width * formats[i].pixel_size);
19144 hr = IDirect3DTexture9_UnlockRect(texture, 0);
19145 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
19147 if (tests[j].pool == D3DPOOL_SYSTEMMEM)
19149 texture_sysmem = texture;
19150 hr = IDirect3DDevice9_CreateTexture(device, tests[j].width, 4, 1, 0,
19151 formats[i].format, D3DPOOL_DEFAULT, &texture, NULL);
19152 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
19154 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture_sysmem,
19155 (IDirect3DBaseTexture9 *)texture);
19156 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
19159 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
19160 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
19161 hr = IDirect3DDevice9_SetPixelShader(device, shader_alpha);
19162 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
19164 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
19165 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19166 hr = IDirect3DDevice9_BeginScene(device);
19167 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19168 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
19169 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19170 hr = IDirect3DDevice9_EndScene(device);
19171 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19173 for (y = 0; y < 4; y++)
19175 for (x = 0; x < tests[j].width; x++)
19177 BOOL r200_broken = formats[i].alpha_broken && alpha_broken[y][x];
19178 if (formats[i].alpha)
19179 expected_color = expected_alpha[y][x];
19180 else
19181 expected_color = 0x00ffff00;
19183 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
19184 ok(color_match(color, expected_color, 1) || broken(r200_broken),
19185 "Expected color 0x%08x, got 0x%08x, format %s, test %u, location %ux%u.\n",
19186 expected_color, color, formats[i].name, j, x, y);
19189 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19190 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19192 hr = IDirect3DDevice9_SetPixelShader(device, shader);
19193 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
19195 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
19196 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19197 hr = IDirect3DDevice9_BeginScene(device);
19198 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19199 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
19200 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19201 hr = IDirect3DDevice9_EndScene(device);
19202 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19204 for (y = 0; y < 4; y++)
19206 for (x = 0; x < tests[j].width; x++)
19208 expected_color = expected_colors[y][x];
19209 if (!formats[i].blue)
19210 expected_color |= 0x000000ff;
19212 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
19213 ok(color_match(color, expected_color, formats[i].slop)
19214 || broken(color_match(color, expected_color, formats[i].slop_broken)),
19215 "Expected color 0x%08x, got 0x%08x, format %s, test %u, location %ux%u.\n",
19216 expected_color, color, formats[i].name, j, x, y);
19219 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19220 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19222 if (tests[j].pool != D3DPOOL_SYSTEMMEM)
19224 IDirect3DTexture9_Release(texture);
19225 continue;
19228 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &dst_surface);
19229 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x.\n", hr);
19230 IDirect3DTexture9_GetSurfaceLevel(texture_sysmem, 0, &src_surface);
19231 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x.\n", hr);
19233 hr = IDirect3DDevice9_UpdateSurface(device, src_surface,
19234 &tests[j].src_rect, dst_surface, &tests[j].dst_point);
19235 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
19237 IDirect3DSurface9_Release(dst_surface);
19238 IDirect3DSurface9_Release(src_surface);
19240 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00003300, 0.0f, 0);
19241 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[0], 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 for (y = 0; y < 4; y++)
19251 for (x = 0; x < tests[j].width; x++)
19253 if (tests[j].width == 4)
19254 expected_color = expected_colors2[y][x];
19255 else
19256 expected_color = expected_colors3[y];
19258 if (!formats[i].blue)
19259 expected_color |= 0x000000ff;
19261 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
19262 ok(color_match(color, expected_color, formats[i].slop)
19263 || broken(color_match(color, expected_color, formats[i].slop_broken)),
19264 "Expected color 0x%08x, got 0x%08x, format %s, test %u, location %ux%u.\n",
19265 expected_color, color, formats[i].name, j, x, y);
19268 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19269 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19271 IDirect3DTexture9_Release(texture_sysmem);
19272 IDirect3DTexture9_Release(texture);
19276 IDirect3DPixelShader9_Release(shader);
19277 IDirect3DPixelShader9_Release(shader_alpha);
19279 done:
19280 refcount = IDirect3DDevice9_Release(device);
19281 ok(!refcount, "Device has %u references left.\n", refcount);
19282 IDirect3D9_Release(d3d);
19283 DestroyWindow(window);
19286 static void test_multisample_mismatch(void)
19288 IDirect3DDevice9 *device;
19289 IDirect3D9 *d3d;
19290 HWND window;
19291 HRESULT hr;
19292 D3DCOLOR color;
19293 ULONG refcount;
19294 IDirect3DSurface9 *rt, *rt_multi, *ds;
19295 static const struct
19297 struct vec3 position;
19298 DWORD color;
19300 quad[] =
19302 {{ -1.0f, -1.0f, 0.0f}, 0x000000ff},
19303 {{ -1.0f, 1.0f, 0.0f}, 0x000000ff},
19304 {{ 1.0f, -1.0f, 1.0f}, 0x000000ff},
19305 {{ 1.0f, 1.0f, 1.0f}, 0x000000ff},
19308 window = create_window();
19309 d3d = Direct3DCreate9(D3D_SDK_VERSION);
19310 ok(!!d3d, "Failed to create a D3D object.\n");
19311 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
19312 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
19314 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample mismatch test.\n");
19315 IDirect3D9_Release(d3d);
19316 return;
19318 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
19319 D3DFMT_D24X8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
19321 skip("Multisampling not supported for D3DFMT_D24X8, skipping multisample mismatch test.\n");
19322 IDirect3D9_Release(d3d);
19323 return;
19326 if (!(device = create_device(d3d, window, window, TRUE)))
19328 skip("Failed to create a D3D device, skipping tests.\n");
19329 IDirect3D9_Release(d3d);
19330 DestroyWindow(window);
19331 return;
19334 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
19335 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt_multi, NULL);
19336 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
19338 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.1f, 0);
19339 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19341 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
19342 ok(SUCCEEDED(hr), "Failed to set depth stencil, hr %#x.\n", hr);
19343 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
19344 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
19345 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
19346 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19348 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
19349 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19350 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
19351 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19353 /* Clear with incompatible buffers. Partial and combined clears. */
19354 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
19355 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19356 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.3f, 0);
19357 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19358 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 0.5f, 0);
19359 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19361 /* The color buffer is reliably cleared on AMD and Nvidia GPUs. */
19362 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
19363 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19364 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
19365 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
19366 color = getPixelColor(device, 320, 240);
19367 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
19368 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19369 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19371 /* Check depth buffer values. AMD GPUs (r500 and evergreen tested) clear the depth buffer
19372 * like you'd expect in a correct framebuffer setup. Nvidia doesn't clear it, neither in
19373 * the Z only clear case nor in the combined clear case. */
19374 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
19375 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
19376 hr = IDirect3DDevice9_BeginScene(device);
19377 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19378 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19379 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19380 hr = IDirect3DDevice9_EndScene(device);
19381 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19382 color = getPixelColor(device, 62, 240);
19383 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
19384 color = getPixelColor(device, 64, 240);
19385 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x000000ff, 1)),
19386 "Got unexpected color 0x%08x.\n", color);
19387 color = getPixelColor(device, 318, 240);
19388 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x000000ff, 1)),
19389 "Got unexpected color 0x%08x.\n", color);
19390 color = getPixelColor(device, 322, 240);
19391 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
19392 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19393 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19395 /* Draw with incompatible buffers. AMD even performs Z testing, and the Z test
19396 * results appear to be correct for this simple draw. Nvidia doesn't draw unless
19397 * the depth test is disabled. Setting ZFUNC = ALWAYS doesn't make the geometry
19398 * show up either. Only test the ZENABLE = FALSE case for now. */
19399 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
19400 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19401 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
19402 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19403 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
19404 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19405 hr = IDirect3DDevice9_BeginScene(device);
19406 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19407 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19408 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19409 hr = IDirect3DDevice9_EndScene(device);
19410 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19412 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
19413 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19414 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
19415 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
19416 color = getPixelColor(device, 320, 240);
19417 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
19418 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19419 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19421 IDirect3DSurface9_Release(ds);
19423 /* Test the reverse situation: Multisampled depth buffer, single sampled color buffer.
19424 * Color clears work as expected, AMD also clears the depth buffer, Nvidia does not. */
19425 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24X8,
19426 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
19427 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#x.\n", hr);
19428 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
19429 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
19430 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
19431 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19432 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ffff00, 0.1f, 0);
19433 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19435 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
19436 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19437 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
19438 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19439 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.3f, 0);
19440 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19441 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 0.5f, 0);
19442 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19444 color = getPixelColor(device, 320, 240);
19445 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
19446 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19447 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19449 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
19450 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19451 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
19452 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19453 hr = IDirect3DDevice9_BeginScene(device);
19454 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19455 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19456 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19457 hr = IDirect3DDevice9_EndScene(device);
19458 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19460 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
19461 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19462 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
19463 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
19464 color = getPixelColor(device, 62, 240);
19465 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
19466 color = getPixelColor(device, 318, 240);
19467 ok(color_match(color, 0x00ffff00, 1) || broken(color_match(color, 0x000000ff, 1)),
19468 "Got unexpected color 0x%08x.\n", color);
19469 color = getPixelColor(device, 322, 240);
19470 ok(color_match(color, 0x00ffff00, 1), "Got unexpected color 0x%08x.\n", color);
19471 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19472 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19474 /* Draw with a single sampled color buffer and a multisampled depth buffer. Again
19475 * AMD seems to perform correct Z testing, Nvidia doesn't draw unless the Z test
19476 * is disabled. Again only test the ZENABLE = FALSE case. */
19477 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
19478 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19479 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
19480 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19481 hr = IDirect3DDevice9_BeginScene(device);
19482 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19483 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19484 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19485 hr = IDirect3DDevice9_EndScene(device);
19486 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19487 color = getPixelColor(device, 320, 240);
19488 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
19489 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19490 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19492 IDirect3DSurface9_Release(rt);
19493 IDirect3DSurface9_Release(ds);
19494 IDirect3DSurface9_Release(rt_multi);
19496 refcount = IDirect3DDevice9_Release(device);
19497 ok(!refcount, "Device has %u references left.\n", refcount);
19498 IDirect3D9_Release(d3d);
19499 DestroyWindow(window);
19502 static void test_texcoordindex(void)
19504 static const D3DMATRIX mat =
19506 1.0f, 0.0f, 0.0f, 0.0f,
19507 0.0f, 0.0f, 0.0f, 0.0f,
19508 0.0f, 0.0f, 0.0f, 0.0f,
19509 0.0f, 0.0f, 0.0f, 0.0f,
19510 }}};
19511 static const struct
19513 struct vec3 pos;
19514 struct vec2 texcoord1;
19515 struct vec2 texcoord2;
19516 struct vec2 texcoord3;
19518 quad[] =
19520 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 1.0f}},
19521 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 0.0f}},
19522 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}, {1.0f, 0.0f}, {0.0f, 1.0f}},
19523 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 0.0f}},
19525 IDirect3DDevice9 *device;
19526 IDirect3D9 *d3d9;
19527 HWND window;
19528 HRESULT hr;
19529 IDirect3DTexture9 *texture1, *texture2;
19530 D3DLOCKED_RECT locked_rect;
19531 ULONG refcount;
19532 D3DCOLOR color;
19533 DWORD *ptr;
19535 window = create_window();
19536 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
19537 ok(!!d3d9, "Failed to create a D3D object.\n");
19538 if (!(device = create_device(d3d9, window, window, TRUE)))
19540 skip("Failed to create a D3D device, skipping tests.\n");
19541 IDirect3D9_Release(d3d9);
19542 DestroyWindow(window);
19543 return;
19546 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture1, NULL);
19547 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
19548 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
19549 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
19551 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
19552 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
19553 ptr = locked_rect.pBits;
19554 ptr[0] = 0xff000000;
19555 ptr[1] = 0xff00ff00;
19556 ptr[2] = 0xff0000ff;
19557 ptr[3] = 0xff00ffff;
19558 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
19559 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
19561 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
19562 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
19563 ptr = locked_rect.pBits;
19564 ptr[0] = 0xff000000;
19565 ptr[1] = 0xff0000ff;
19566 ptr[2] = 0xffff0000;
19567 ptr[3] = 0xffff00ff;
19568 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
19569 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
19571 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture1);
19572 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
19573 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *)texture2);
19574 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
19575 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX3);
19576 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
19577 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
19578 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
19579 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
19580 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
19581 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
19582 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
19583 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
19584 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
19585 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
19586 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
19587 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
19588 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
19589 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
19590 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
19592 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXCOORDINDEX, 1);
19593 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
19594 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 0);
19595 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
19597 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
19598 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19600 hr = IDirect3DDevice9_BeginScene(device);
19601 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19602 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19603 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19604 hr = IDirect3DDevice9_EndScene(device);
19605 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19607 color = getPixelColor(device, 160, 120);
19608 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
19609 color = getPixelColor(device, 480, 120);
19610 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19611 color = getPixelColor(device, 160, 360);
19612 ok(color_match(color, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color);
19613 color = getPixelColor(device, 480, 360);
19614 ok(color_match(color, 0x00ffffff, 2), "Got unexpected color 0x%08x.\n", color);
19616 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
19617 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
19618 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE1, &mat);
19619 ok(SUCCEEDED(hr), "Failed to set transformation matrix, hr %#x.\n", hr);
19621 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
19622 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19624 hr = IDirect3DDevice9_BeginScene(device);
19625 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19626 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19627 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19628 hr = IDirect3DDevice9_EndScene(device);
19629 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19631 color = getPixelColor(device, 160, 120);
19632 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
19633 color = getPixelColor(device, 480, 120);
19634 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19635 color = getPixelColor(device, 160, 360);
19636 ok(color_match(color, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color);
19637 color = getPixelColor(device, 480, 360);
19638 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19640 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
19641 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
19642 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 2);
19643 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
19645 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
19646 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19648 hr = IDirect3DDevice9_BeginScene(device);
19649 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19650 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19651 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19652 hr = IDirect3DDevice9_EndScene(device);
19653 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19655 color = getPixelColor(device, 160, 120);
19656 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
19657 color = getPixelColor(device, 480, 120);
19658 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19659 color = getPixelColor(device, 160, 360);
19660 ok(color_match(color, 0x00ff00ff, 2), "Got unexpected color 0x%08x.\n", color);
19661 color = getPixelColor(device, 480, 360);
19662 ok(color_match(color, 0x00ffff00, 2), "Got unexpected color 0x%08x.\n", color);
19664 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19665 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19667 IDirect3DTexture9_Release(texture1);
19668 IDirect3DTexture9_Release(texture2);
19670 refcount = IDirect3DDevice9_Release(device);
19671 ok(!refcount, "Device has %u references left.\n", refcount);
19672 IDirect3D9_Release(d3d9);
19673 DestroyWindow(window);
19676 static void test_vertex_blending(void)
19678 IDirect3DVertexDeclaration9 *vertex_declaration;
19679 IDirect3DDevice9 *device;
19680 IDirect3D9 *d3d;
19681 D3DCAPS9 caps;
19682 D3DCOLOR color;
19683 ULONG refcount;
19684 HWND window;
19685 HRESULT hr;
19686 int i;
19688 static const D3DMATRIX view_mat =
19690 2.0f / 10.0f, 0.0f, 0.0f, 0.0f,
19691 0.0f, 2.0f / 10.0f, 0.0f, 0.0f,
19692 0.0f, 0.0f, 1.0f, 0.0f,
19693 0.0f, 0.0f, 0.0f, 1.0f
19694 }}},
19695 upper_left =
19697 1.0f, 0.0f, 0.0f, 0.0f,
19698 0.0f, 1.0f, 0.0f, 0.0f,
19699 0.0f, 0.0f, 1.0f, 0.0f,
19700 -4.0f, 4.0f, 0.0f, 1.0f
19701 }}},
19702 lower_left =
19704 1.0f, 0.0f, 0.0f, 0.0f,
19705 0.0f, 1.0f, 0.0f, 0.0f,
19706 0.0f, 0.0f, 1.0f, 0.0f,
19707 -4.0f, -4.0f, 0.0f, 1.0f
19708 }}},
19709 upper_right =
19711 1.0f, 0.0f, 0.0f, 0.0f,
19712 0.0f, 1.0f, 0.0f, 0.0f,
19713 0.0f, 0.0f, 1.0f, 0.0f,
19714 4.0f, 4.0f, 0.0f, 1.0f
19715 }}},
19716 lower_right =
19718 1.0f, 0.0f, 0.0f, 0.0f,
19719 0.0f, 1.0f, 0.0f, 0.0f,
19720 0.0f, 0.0f, 1.0f, 0.0f,
19721 4.0f, -4.0f, 0.0f, 1.0f
19722 }}};
19724 static const POINT quad_upper_right_points[] =
19726 {576, 48}, {-1, -1},
19728 quad_upper_right_empty_points[] =
19730 {64, 48}, {64, 432}, {576, 432}, {320, 240}, {-1, -1}
19732 quad_center_points[] =
19734 {320, 240}, {-1, -1}
19736 quad_center_empty_points[] =
19738 {64, 48}, {576, 48}, {64, 432}, {576, 432}, {-1, -1}
19740 quad_upper_center_points[] =
19742 {320, 48}, {-1, -1}
19744 quad_upper_center_empty_points[] =
19746 {320, 240}, {64, 48}, {576, 48}, {-1, -1}
19748 quad_fullscreen_points[] =
19750 {320, 48}, {320, 240}, {64, 48}, {576, 48}, {64, 432}, {576, 432}, {-1, -1}
19752 quad_fullscreen_empty_points[] =
19754 {-1, -1}
19757 static const struct
19759 DWORD fvf;
19760 D3DVERTEXELEMENT9 decl_elements[3];
19761 struct
19763 struct
19765 struct vec3 position;
19766 struct vec3 blendweights;
19768 vertex_data_float[4];
19769 struct
19771 struct vec3 position;
19772 D3DCOLOR blendweights;
19774 vertex_data_d3dcolor[4];
19775 } s;
19776 const POINT *quad_points;
19777 const POINT *empty_points;
19779 tests[] =
19781 /* upper right */
19783 D3DFVF_XYZB3,
19784 {{0}},
19785 {{{{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
19786 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
19787 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
19788 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}}}},
19789 quad_upper_right_points, quad_upper_right_empty_points
19791 /* center */
19793 D3DFVF_XYZB3,
19794 {{0}},
19795 {{{{-1.0f, -1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}},
19796 {{-1.0f, 1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}},
19797 {{ 1.0f, -1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}},
19798 {{ 1.0f, 1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}}}},
19799 quad_center_points, quad_center_empty_points
19801 /* upper center */
19803 D3DFVF_XYZB3,
19804 {{0}},
19805 {{{{-1.0f, -1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}},
19806 {{-1.0f, 1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}},
19807 {{ 1.0f, -1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}},
19808 {{ 1.0f, 1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}}}},
19809 quad_upper_center_points, quad_upper_center_empty_points
19811 /* full screen */
19813 D3DFVF_XYZB3,
19814 {{0}},
19815 {{{{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}},
19816 {{-1.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}},
19817 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}},
19818 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}}}},
19819 quad_fullscreen_points, quad_fullscreen_empty_points
19821 /* D3DCOLOR, full screen */
19825 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
19826 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
19827 D3DDECL_END()
19829 {{{{0}}},
19830 {{{-1.0f, -1.0f, 0.0f}, 0x0000ff00},
19831 {{-1.0f, 1.0f, 0.0f}, 0x00ff0000},
19832 {{ 1.0f, -1.0f, 0.0f}, 0x000000ff},
19833 {{ 1.0f, 1.0f, 0.0f}, 0x00000000}}},
19834 quad_fullscreen_points, quad_fullscreen_empty_points
19838 window = create_window();
19839 d3d = Direct3DCreate9(D3D_SDK_VERSION);
19840 ok(!!d3d, "Failed to create a D3D object.\n");
19841 if (!(device = create_device(d3d, window, window, TRUE)))
19843 skip("Failed to create a D3D device, skipping tests.\n");
19844 goto done;
19847 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
19848 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
19849 if (caps.MaxVertexBlendMatrices < 4)
19851 skip("Only %u vertex blend matrices supported, skipping tests.\n", caps.MaxVertexBlendMatrices);
19852 IDirect3DDevice9_Release(device);
19853 goto done;
19856 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
19857 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
19859 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &view_mat);
19860 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19862 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &upper_left);
19863 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19864 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(1), &lower_left);
19865 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19866 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(2), &lower_right);
19867 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19868 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(3), &upper_right);
19869 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19871 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_VERTEXBLEND, D3DVBF_3WEIGHTS);
19872 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed %08x\n", hr);
19874 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
19876 const POINT *point;
19878 if (tests[i].fvf)
19880 hr = IDirect3DDevice9_SetFVF(device, tests[i].fvf);
19881 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
19882 vertex_declaration = NULL;
19884 else
19886 hr = IDirect3DDevice9_CreateVertexDeclaration(device, tests[i].decl_elements, &vertex_declaration);
19887 ok(SUCCEEDED(hr), "Failed to create vertex declaration, hr %#x.\n", hr);
19888 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
19889 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
19892 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
19893 ok(SUCCEEDED(hr), "Failed to clear %08x\n", hr);
19895 hr = IDirect3DDevice9_BeginScene(device);
19896 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19898 if (tests[i].fvf)
19899 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
19900 tests[i].s.vertex_data_float, sizeof(*tests[i].s.vertex_data_float));
19901 else
19902 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
19903 tests[i].s.vertex_data_d3dcolor, sizeof(*tests[i].s.vertex_data_d3dcolor));
19904 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19906 hr = IDirect3DDevice9_EndScene(device);
19907 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19909 point = tests[i].quad_points;
19910 while (point->x != -1 && point->y != -1)
19912 color = getPixelColor(device, point->x, point->y);
19913 ok(color_match(color, 0x00ffffff, 1), "Expected quad at %dx%d.\n", point->x, point->y);
19914 ++point;
19917 point = tests[i].empty_points;
19918 while (point->x != -1 && point->y != -1)
19920 color = getPixelColor(device, point->x, point->y);
19921 ok(color_match(color, 0x00000000, 1), "Unexpected quad at %dx%d.\n", point->x, point->y);
19922 ++point;
19925 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19926 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19928 if (vertex_declaration)
19929 IDirect3DVertexDeclaration9_Release(vertex_declaration);
19932 refcount = IDirect3DDevice9_Release(device);
19933 ok(!refcount, "Device has %u references left.\n", refcount);
19935 done:
19936 IDirect3D9_Release(d3d);
19937 DestroyWindow(window);
19940 static void test_updatetexture(void)
19942 BOOL r32f_supported, ati2n_supported, do_visual_test;
19943 IDirect3DBaseTexture9 *src, *dst;
19944 unsigned int t, i, f, l, x, y, z;
19945 D3DLOCKED_RECT locked_rect;
19946 D3DLOCKED_BOX locked_box;
19947 IDirect3DDevice9 *device;
19948 IDirect3D9 *d3d9;
19949 ULONG refcount;
19950 D3DCOLOR color;
19951 D3DCAPS9 caps;
19952 HWND window;
19953 HRESULT hr;
19954 static const struct
19956 struct vec3 pos;
19957 struct vec2 texcoord;
19959 quad[] =
19961 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}},
19962 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}},
19963 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}},
19964 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
19966 static const struct
19968 struct vec3 pos;
19969 struct vec3 texcoord;
19971 quad_cube_tex[] =
19973 {{-1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, 0.5f}},
19974 {{-1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, 0.5f}},
19975 {{ 1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, -0.5f}},
19976 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, -0.5f}},
19978 static const struct
19980 UINT src_width, src_height;
19981 UINT dst_width, dst_height;
19982 UINT src_levels, dst_levels;
19983 D3DFORMAT src_format, dst_format;
19984 BOOL broken;
19986 tests[] =
19988 {8, 8, 8, 8, 0, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 0 */
19989 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 1 */
19990 {8, 8, 8, 8, 2, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 2 */
19991 {8, 8, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 3 */
19992 {8, 8, 8, 8, 4, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 4 */
19993 {8, 8, 2, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 5 */
19994 /* The WARP renderer doesn't handle these cases correctly. */
19995 {8, 8, 8, 8, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 6 */
19996 {8, 8, 4, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 7 */
19997 /* Not clear what happens here on Windows, it doesn't make much sense
19998 * though (on Nvidia it seems to upload the 4x4 surface into the 7x7
19999 * one or something like that). */
20000 /* {8, 8, 7, 7, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
20001 {8, 8, 8, 8, 1, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 8 */
20002 {4, 4, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 9 */
20003 /* This one causes weird behavior on Windows (it probably writes out
20004 * of the texture memory). */
20005 /* {8, 8, 4, 4, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
20006 {8, 4, 4, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 10 */
20007 {8, 4, 2, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 11 */
20008 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8, FALSE}, /* 12 */
20009 {8, 8, 8, 8, 4, 4, D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 13 */
20010 /* The data is converted correctly on AMD, on Nvidia nothing happens
20011 * (it draws a black quad). */
20012 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_R5G6B5, TRUE}, /* 14 */
20013 /* Here the data is converted on AMD, just copied and "reinterpreted" as
20014 * a 32 bit float on Nvidia (specifically the tested value becomes a
20015 * very small float number which we get as 0 in the test). */
20016 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_R32F, TRUE}, /* 15 */
20017 /* This one doesn't seem to give the expected results on AMD. */
20018 /* {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_Q8W8V8U8, FALSE}, */
20019 {8, 8, 8, 8, 4, 4, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 16 */
20020 {8, 8, 8, 8, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 17 */
20021 {8, 8, 2, 2, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 18 */
20023 static const struct
20025 D3DRESOURCETYPE type;
20026 DWORD fvf;
20027 const void *quad;
20028 unsigned int vertex_size;
20029 DWORD cap;
20030 const char *name;
20032 texture_types[] =
20034 {D3DRTYPE_TEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
20035 quad, sizeof(*quad), D3DPTEXTURECAPS_MIPMAP, "2D mipmapped"},
20037 {D3DRTYPE_CUBETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0),
20038 quad_cube_tex, sizeof(*quad_cube_tex), D3DPTEXTURECAPS_CUBEMAP, "Cube"},
20040 {D3DRTYPE_VOLUMETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
20041 quad, sizeof(*quad), D3DPTEXTURECAPS_VOLUMEMAP, "Volume"}
20044 window = create_window();
20045 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
20046 ok(!!d3d9, "Failed to create a D3D object.\n");
20047 if (!(device = create_device(d3d9, window, window, TRUE)))
20049 skip("Failed to create a D3D device, skipping tests.\n");
20050 IDirect3D9_Release(d3d9);
20051 DestroyWindow(window);
20052 return;
20055 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
20056 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
20058 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
20059 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#x.\n", hr);
20060 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
20061 ok(SUCCEEDED(hr), "Failed to set texture clamping state, hr %#x.\n", hr);
20062 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
20063 ok(SUCCEEDED(hr), "Failed to set texture clamping state, hr %#x.\n", hr);
20064 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
20065 ok(SUCCEEDED(hr), "Failed to set texture clamping state, hr %#x.\n", hr);
20066 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
20067 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20068 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
20069 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#x.\n", hr);
20070 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
20071 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#x.\n", hr);
20073 for (t = 0; t < sizeof(texture_types) / sizeof(*texture_types); ++t)
20075 if (!(caps.TextureCaps & texture_types[t].cap))
20077 skip("%s textures not supported, skipping some tests.\n", texture_types[t].name);
20078 continue;
20080 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20081 D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_FILTER, texture_types[t].type, D3DFMT_A8R8G8B8)))
20083 skip("%s D3DFMT_A8R8G8B8 texture filtering is not supported, skipping some tests.\n",
20084 texture_types[t].name);
20085 continue;
20087 r32f_supported = TRUE;
20088 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20089 D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_FILTER, texture_types[t].type, D3DFMT_R32F)))
20091 skip("%s R32F textures are not supported, skipping some tests.\n", texture_types[t].name);
20092 r32f_supported = FALSE;
20094 ati2n_supported = TRUE;
20095 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20096 D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_FILTER, texture_types[t].type, MAKEFOURCC('A','T','I','2'))))
20098 skip("%s ATI2N textures are not supported, skipping some tests.\n", texture_types[t].name);
20099 ati2n_supported = FALSE;
20102 hr = IDirect3DDevice9_SetFVF(device, texture_types[t].fvf);
20103 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
20105 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
20107 if (tests[i].dst_format == D3DFMT_R32F && !r32f_supported)
20108 continue;
20109 if (tests[i].dst_format == MAKEFOURCC('A','T','I','2') && !ati2n_supported)
20110 continue;
20112 switch (texture_types[t].type)
20114 case D3DRTYPE_TEXTURE:
20115 hr = IDirect3DDevice9_CreateTexture(device,
20116 tests[i].src_width, tests[i].src_height,
20117 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
20118 (IDirect3DTexture9 **)&src, NULL);
20119 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
20120 hr = IDirect3DDevice9_CreateTexture(device,
20121 tests[i].dst_width, tests[i].dst_height,
20122 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
20123 (IDirect3DTexture9 **)&dst, NULL);
20124 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
20125 break;
20126 case D3DRTYPE_CUBETEXTURE:
20127 hr = IDirect3DDevice9_CreateCubeTexture(device,
20128 tests[i].src_width,
20129 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
20130 (IDirect3DCubeTexture9 **)&src, NULL);
20131 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
20132 hr = IDirect3DDevice9_CreateCubeTexture(device,
20133 tests[i].dst_width,
20134 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
20135 (IDirect3DCubeTexture9 **)&dst, NULL);
20136 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
20137 break;
20138 case D3DRTYPE_VOLUMETEXTURE:
20139 hr = IDirect3DDevice9_CreateVolumeTexture(device,
20140 tests[i].src_width, tests[i].src_height, tests[i].src_width,
20141 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
20142 (IDirect3DVolumeTexture9 **)&src, NULL);
20143 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
20144 hr = IDirect3DDevice9_CreateVolumeTexture(device,
20145 tests[i].dst_width, tests[i].dst_height, tests[i].dst_width,
20146 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
20147 (IDirect3DVolumeTexture9 **)&dst, NULL);
20148 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
20149 break;
20150 default:
20151 trace("Unexpected resource type.\n");
20154 /* Skip the visual part of the test for ATI2N (laziness) and cases that
20155 * give a different (and unlikely to be useful) result. */
20156 do_visual_test = (tests[i].src_format == D3DFMT_A8R8G8B8 || tests[i].src_format == D3DFMT_X8R8G8B8)
20157 && tests[i].src_levels != 0
20158 && tests[i].src_width >= tests[i].dst_width && tests[i].src_height >= tests[i].dst_height
20159 && !(tests[i].src_width > tests[i].src_height && tests[i].dst_width < tests[i].dst_height);
20161 if (do_visual_test)
20163 DWORD *ptr = NULL;
20164 unsigned int width, height, depth, row_pitch = 0, slice_pitch = 0;
20166 for (f = 0; f < (texture_types[t].type == D3DRTYPE_CUBETEXTURE ? 6 : 1); ++f)
20168 width = tests[i].src_width;
20169 height = texture_types[t].type != D3DRTYPE_CUBETEXTURE ? tests[i].src_height : tests[i].src_width;
20170 depth = texture_types[t].type == D3DRTYPE_VOLUMETEXTURE ? width : 1;
20172 for (l = 0; l < tests[i].src_levels; ++l)
20174 switch (texture_types[t].type)
20176 case D3DRTYPE_TEXTURE:
20177 hr = IDirect3DTexture9_LockRect((IDirect3DTexture9 *)src,
20178 l, &locked_rect, NULL, 0);
20179 ptr = locked_rect.pBits;
20180 row_pitch = locked_rect.Pitch / sizeof(*ptr);
20181 break;
20182 case D3DRTYPE_CUBETEXTURE:
20183 hr = IDirect3DCubeTexture9_LockRect((IDirect3DCubeTexture9 *)src,
20184 f, l, &locked_rect, NULL, 0);
20185 ptr = locked_rect.pBits;
20186 row_pitch = locked_rect.Pitch / sizeof(*ptr);
20187 break;
20188 case D3DRTYPE_VOLUMETEXTURE:
20189 hr = IDirect3DVolumeTexture9_LockBox((IDirect3DVolumeTexture9 *)src,
20190 l, &locked_box, NULL, 0);
20191 ptr = locked_box.pBits;
20192 row_pitch = locked_box.RowPitch / sizeof(*ptr);
20193 slice_pitch = locked_box.SlicePitch / sizeof(*ptr);
20194 break;
20195 default:
20196 trace("Unexpected resource type.\n");
20198 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
20200 for (z = 0; z < depth; ++z)
20202 for (y = 0; y < height; ++y)
20204 for (x = 0; x < width; ++x)
20206 ptr[z * slice_pitch + y * row_pitch + x] = 0xff000000
20207 | (DWORD)(x / (width - 1.0f) * 255.0f) << 16
20208 | (DWORD)(y / (height - 1.0f) * 255.0f) << 8;
20213 switch (texture_types[t].type)
20215 case D3DRTYPE_TEXTURE:
20216 hr = IDirect3DTexture9_UnlockRect((IDirect3DTexture9 *)src, l);
20217 break;
20218 case D3DRTYPE_CUBETEXTURE:
20219 hr = IDirect3DCubeTexture9_UnlockRect((IDirect3DCubeTexture9 *)src, f, l);
20220 break;
20221 case D3DRTYPE_VOLUMETEXTURE:
20222 hr = IDirect3DVolumeTexture9_UnlockBox((IDirect3DVolumeTexture9 *)src, l);
20223 break;
20224 default:
20225 trace("Unexpected resource type.\n");
20227 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
20229 width >>= 1;
20230 if (!width)
20231 width = 1;
20232 height >>= 1;
20233 if (!height)
20234 height = 1;
20235 depth >>= 1;
20236 if (!depth)
20237 depth = 1;
20242 hr = IDirect3DDevice9_UpdateTexture(device, src, dst);
20243 if (FAILED(hr))
20245 todo_wine ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u, %u.\n", hr, t, i);
20246 IDirect3DBaseTexture9_Release(src);
20247 IDirect3DBaseTexture9_Release(dst);
20248 continue;
20250 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u, %u.\n", hr, t, i);
20252 if (do_visual_test)
20254 hr = IDirect3DDevice9_SetTexture(device, 0, dst);
20255 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
20257 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 1.0f, 0);
20258 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
20260 hr = IDirect3DDevice9_BeginScene(device);
20261 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
20262 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
20263 texture_types[t].quad, texture_types[t].vertex_size);
20264 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20265 hr = IDirect3DDevice9_EndScene(device);
20266 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
20268 color = getPixelColor(device, 320, 240);
20269 ok (color_match(color, 0x007f7f00, 3) || broken(tests[i].broken)
20270 || broken(color == 0x00adbeef), /* WARP device often just breaks down. */
20271 "Got unexpected color 0x%08x, case %u, %u.\n", color, t, i);
20274 IDirect3DBaseTexture9_Release(src);
20275 IDirect3DBaseTexture9_Release(dst);
20278 refcount = IDirect3DDevice9_Release(device);
20279 ok(!refcount, "Device has %u references left.\n", refcount);
20280 IDirect3D9_Release(d3d9);
20281 DestroyWindow(window);
20284 static void test_depthbias(void)
20286 IDirect3DDevice9 *device;
20287 IDirect3D9 *d3d;
20288 IDirect3DSurface9 *ds;
20289 D3DCAPS9 caps;
20290 D3DCOLOR color;
20291 ULONG refcount;
20292 HWND window;
20293 HRESULT hr;
20294 unsigned int i;
20295 static const D3DFORMAT formats[] =
20297 D3DFMT_D16, D3DFMT_D24X8, D3DFMT_D32, D3DFMT_D24S8, MAKEFOURCC('I','N','T','Z'),
20299 /* The scaling factor detection function detects the wrong factor for
20300 * float formats on Nvidia, therefore the following tests are disabled.
20301 * The wined3d function detects 2^23 like for fixed point formats but
20302 * the test needs 2^22 to pass.
20304 * AMD GPUs need a different scaling factor for float depth buffers
20305 * (2^24) than fixed point (2^23), but the wined3d detection function
20306 * works there, producing the right result in the test.
20308 * D3DFMT_D32F_LOCKABLE, D3DFMT_D24FS8,
20312 static const struct
20314 struct vec3 position;
20316 quad[] =
20318 {{-1.0f, -1.0f, 0.0f}},
20319 {{-1.0f, 1.0f, 0.0f}},
20320 {{ 1.0f, -1.0f, 1.0f}},
20321 {{ 1.0f, 1.0f, 1.0f}},
20323 union
20325 float f;
20326 DWORD d;
20327 } conv;
20329 window = create_window();
20330 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20331 ok(!!d3d, "Failed to create a D3D object.\n");
20332 if (!(device = create_device(d3d, window, window, TRUE)))
20334 skip("Failed to create a D3D device, skipping tests.\n");
20335 goto done;
20338 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
20339 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
20340 if (!(caps.RasterCaps & D3DPRASTERCAPS_DEPTHBIAS))
20342 IDirect3DDevice9_Release(device);
20343 skip("D3DPRASTERCAPS_DEPTHBIAS not supported.\n");
20344 goto done;
20347 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
20348 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
20349 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
20350 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
20351 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
20352 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
20353 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
20354 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
20355 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
20356 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
20358 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
20360 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20361 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, formats[i])))
20363 skip("Depth format %u not supported, skipping.\n", formats[i]);
20364 continue;
20367 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, formats[i],
20368 D3DMULTISAMPLE_NONE, 0, FALSE, &ds, NULL);
20369 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
20370 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
20371 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
20372 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 0.5f, 0);
20373 ok(SUCCEEDED(hr), "Failed to clear %08x\n", hr);
20375 hr = IDirect3DDevice9_BeginScene(device);
20376 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
20378 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x00ff0000);
20379 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20380 conv.f = -0.2f;
20381 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
20382 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20383 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20384 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20386 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
20387 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20388 conv.f = 0.0f;
20389 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
20390 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20391 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20392 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20394 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x000000ff);
20395 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20396 conv.f = 0.2f;
20397 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
20398 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20399 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20400 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20402 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x00ffffff);
20403 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20404 conv.f = 0.4f;
20405 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
20406 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20407 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20408 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20410 color = getPixelColor(device, 61, 240);
20411 ok(color_match(color, 0x00ffffff, 1), "Got unexpected color %08x at x=62, format %u.\n", color, formats[i]);
20412 color = getPixelColor(device, 65, 240);
20414 /* The broken results are for the WARP driver on the testbot. It seems to initialize
20415 * a scaling factor based on the first depth format that is used. Other formats with
20416 * a different depth size then render incorrectly. */
20417 ok(color_match(color, 0x000000ff, 1) || broken(color_match(color, 0x00ffffff, 1)),
20418 "Got unexpected color %08x at x=64, format %u.\n", color, formats[i]);
20419 color = getPixelColor(device, 190, 240);
20420 ok(color_match(color, 0x000000ff, 1) || broken(color_match(color, 0x00ffffff, 1)),
20421 "Got unexpected color %08x at x=190, format %u.\n", color, formats[i]);
20423 color = getPixelColor(device, 194, 240);
20424 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ffffff, 1)),
20425 "Got unexpected color %08x at x=194, format %u.\n", color, formats[i]);
20426 color = getPixelColor(device, 318, 240);
20427 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ffffff, 1)),
20428 "Got unexpected color %08x at x=318, format %u.\n", color, formats[i]);
20430 color = getPixelColor(device, 322, 240);
20431 ok(color_match(color, 0x00ff0000, 1) || broken(color_match(color, 0x00000000, 1)),
20432 "Got unexpected color %08x at x=322, format %u.\n", color, formats[i]);
20433 color = getPixelColor(device, 446, 240);
20434 ok(color_match(color, 0x00ff0000, 1) || broken(color_match(color, 0x00000000, 1)),
20435 "Got unexpected color %08x at x=446, format %u.\n", color, formats[i]);
20437 color = getPixelColor(device, 450, 240);
20438 ok(color_match(color, 0x00000000, 1), "Got unexpected color %08x at x=446, format %u.\n", color, formats[i]);
20440 hr = IDirect3DDevice9_EndScene(device);
20441 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
20443 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20444 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
20445 IDirect3DSurface9_Release(ds);
20448 refcount = IDirect3DDevice9_Release(device);
20449 ok(!refcount, "Device has %u references left.\n", refcount);
20451 done:
20452 IDirect3D9_Release(d3d);
20453 DestroyWindow(window);
20456 static void test_flip(void)
20458 IDirect3DDevice9 *device;
20459 IDirect3D9 *d3d;
20460 ULONG refcount;
20461 HWND window;
20462 HRESULT hr;
20463 IDirect3DSurface9 *back_buffers[3], *test_surface;
20464 unsigned int i;
20465 D3DCOLOR color;
20466 D3DPRESENT_PARAMETERS present_parameters = {0};
20468 window = create_window();
20469 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20470 ok(!!d3d, "Failed to create a D3D object.\n");
20472 present_parameters.BackBufferWidth = 640;
20473 present_parameters.BackBufferHeight = 480;
20474 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
20475 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
20476 present_parameters.hDeviceWindow = window;
20477 present_parameters.Windowed = TRUE;
20478 present_parameters.BackBufferCount = 3;
20479 present_parameters.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
20480 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20481 window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
20482 if (!device)
20484 skip("Failed to create a D3D device, skipping tests.\n");
20485 IDirect3D9_Release(d3d);
20486 DestroyWindow(window);
20487 return;
20490 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
20492 hr = IDirect3DDevice9_GetBackBuffer(device, 0, i, D3DBACKBUFFER_TYPE_MONO, &back_buffers[i]);
20493 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
20495 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &test_surface);
20496 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
20497 ok(test_surface == back_buffers[0], "Expected render target %p, got %p.\n", back_buffers[0], test_surface);
20498 IDirect3DSurface9_Release(test_surface);
20500 hr = IDirect3DDevice9_SetRenderTarget(device, 0, back_buffers[2]);
20501 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
20503 hr = IDirect3DDevice9_ColorFill(device, back_buffers[0], NULL, 0xffff0000);
20504 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x.\n", hr);
20505 hr = IDirect3DDevice9_ColorFill(device, back_buffers[1], NULL, 0xff00ff00);
20506 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x.\n", hr);
20507 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
20508 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
20510 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20511 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20513 /* Render target is unmodified. */
20514 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &test_surface);
20515 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
20516 ok(test_surface == back_buffers[2], "Expected render target %p, got %p.\n", back_buffers[2], test_surface);
20517 IDirect3DSurface9_Release(test_surface);
20519 /* Backbuffer surface pointers are unmodified */
20520 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
20522 hr = IDirect3DDevice9_GetBackBuffer(device, 0, i, D3DBACKBUFFER_TYPE_MONO, &test_surface);
20523 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
20524 ok(test_surface == back_buffers[i], "Expected back buffer %u = %p, got %p.\n",
20525 i, back_buffers[i], test_surface);
20526 IDirect3DSurface9_Release(test_surface);
20529 /* Contents were changed. */
20530 color = getPixelColorFromSurface(back_buffers[0], 1, 1);
20531 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
20532 color = getPixelColorFromSurface(back_buffers[1], 1, 1);
20533 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
20535 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0f, 0);
20536 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
20538 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20539 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20541 color = getPixelColorFromSurface(back_buffers[0], 1, 1);
20542 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
20543 color = getPixelColorFromSurface(back_buffers[1], 1, 1);
20544 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
20546 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20547 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20549 color = getPixelColorFromSurface(back_buffers[0], 1, 1);
20550 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
20552 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
20553 IDirect3DSurface9_Release(back_buffers[i]);
20555 refcount = IDirect3DDevice9_Release(device);
20556 ok(!refcount, "Device has %u references left.\n", refcount);
20558 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20559 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
20561 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample flip test.\n");
20562 goto done;
20565 present_parameters.BackBufferCount = 2;
20566 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
20567 present_parameters.Flags = 0;
20568 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20569 window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
20571 for (i = 0; i < present_parameters.BackBufferCount; ++i)
20573 hr = IDirect3DDevice9_GetBackBuffer(device, 0, i, D3DBACKBUFFER_TYPE_MONO, &back_buffers[i]);
20574 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
20577 hr = IDirect3DDevice9_SetRenderTarget(device, 0, back_buffers[1]);
20578 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
20579 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0f, 0);
20580 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
20582 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20583 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20585 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
20586 D3DMULTISAMPLE_NONE, 0, TRUE, &test_surface, NULL);
20587 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
20588 hr = IDirect3DDevice9_StretchRect(device, back_buffers[0], NULL, test_surface, NULL, D3DTEXF_POINT);
20589 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
20591 color = getPixelColorFromSurface(test_surface, 1, 1);
20592 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
20594 IDirect3DSurface9_Release(test_surface);
20595 for (i = 0; i < present_parameters.BackBufferCount; ++i)
20596 IDirect3DSurface9_Release(back_buffers[i]);
20598 refcount = IDirect3DDevice9_Release(device);
20599 ok(!refcount, "Device has %u references left.\n", refcount);
20601 done:
20602 IDirect3D9_Release(d3d);
20603 DestroyWindow(window);
20606 static void test_uninitialized_varyings(void)
20608 static const D3DMATRIX mat =
20610 1.0f, 0.0f, 0.0f, 0.0f,
20611 0.0f, 1.0f, 0.0f, 0.0f,
20612 0.0f, 0.0f, 1.0f, 0.0f,
20613 0.0f, 0.0f, 0.0f, 1.0f,
20614 }}};
20615 static const struct vec3 quad[] =
20617 {-1.0f, -1.0f, 0.1f},
20618 {-1.0f, 1.0f, 0.1f},
20619 { 1.0f, -1.0f, 0.1f},
20620 { 1.0f, 1.0f, 0.1f},
20622 static const DWORD vs1_code[] =
20624 0xfffe0101, /* vs_1_1 */
20625 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20626 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
20627 0x0000ffff
20629 static const DWORD vs1_partial_code[] =
20631 0xfffe0101, /* vs_1_1 */
20632 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20633 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
20634 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
20635 0x00000001, 0xd0010000, 0xa0e40000, /* mov oD0.x, c0 */
20636 0x00000001, 0xd0010001, 0xa0e40000, /* mov oD1.x, c0 */
20637 0x00000001, 0xe0010000, 0xa0e40000, /* mov oT0.x, c0 */
20638 0x0000ffff
20640 static const DWORD vs2_code[] =
20642 0xfffe0200, /* vs_2_0 */
20643 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20644 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
20645 0x0000ffff
20647 static const DWORD vs2_partial_code[] =
20649 0xfffe0200, /* vs_2_0 */
20650 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20651 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
20652 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
20653 0x02000001, 0xd0010000, 0xa0e40000, /* mov oD0.x, c0 */
20654 0x02000001, 0xd0010001, 0xa0e40000, /* mov oD1.x, c0 */
20655 0x02000001, 0xe0010000, 0xa0e40000, /* mov oT0.x, c0 */
20656 0x0000ffff
20658 static const DWORD vs3_code[] =
20660 0xfffe0300, /* vs_3_0 */
20661 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20662 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
20663 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
20664 0x0000ffff
20666 static const DWORD vs3_partial_code[] =
20668 0xfffe0300, /* vs_3_0 */
20669 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20670 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
20671 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
20672 0x0200001f, 0x8001000a, 0xe00f0002, /* dcl_color1 o2 */
20673 0x0200001f, 0x80000005, 0xe00f0003, /* dcl_texcoord0 o3 */
20674 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
20675 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
20676 0x02000001, 0xe0010001, 0xa0e40000, /* mov o1.x, c0 */
20677 0x02000001, 0xe0010002, 0xa0e40000, /* mov o2.x, c0 */
20678 0x02000001, 0xe0010003, 0xa0e40000, /* mov o3.x, c0 */
20679 0x0000ffff
20681 static const DWORD ps1_diffuse_code[] =
20683 0xffff0101, /* ps_1_1 */
20684 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
20685 0x0000ffff
20687 static const DWORD ps1_specular_code[] =
20689 0xffff0101, /* ps_1_1 */
20690 0x00000001, 0x800f0000, 0x90e40001, /* mov r0, v1 */
20691 0x0000ffff
20693 static const DWORD ps1_texcoord_code[] =
20695 0xffff0101, /* ps_1_1 */
20696 0x00000040, 0xb00f0000, /* texcoord t0 */
20697 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
20698 0x0000ffff
20700 static const DWORD ps2_diffuse_code[] =
20702 0xffff0200, /* ps_2_0 */
20703 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
20704 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
20705 0x0000ffff
20707 static const DWORD ps2_specular_code[] =
20709 0xffff0200, /* ps_2_0 */
20710 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
20711 0x02000001, 0x800f0800, 0x90e40001, /* mov oC0, v1 */
20712 0x0000ffff
20714 static const DWORD ps2_texcoord_code[] =
20716 0xffff0200, /* ps_2_0 */
20717 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
20718 0x02000001, 0x800f0800, 0xb0e40000, /* mov oC0, t0 */
20719 0x0000ffff
20721 #if 0
20722 /* This has been left here for documentation purposes. It is referenced in disabled tests in the table below. */
20723 static const DWORD ps3_diffuse_code[] =
20725 0xffff0300, /* ps_3_0 */
20726 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
20727 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
20728 0x0000ffff
20730 #endif
20731 static const DWORD ps3_specular_code[] =
20733 0xffff0300, /* ps_3_0 */
20734 0x0200001f, 0x8001000a, 0x900f0001, /* dcl_color1 v1 */
20735 0x02000001, 0x800f0800, 0x90e40001, /* mov oC0, v1 */
20736 0x0000ffff
20738 static const DWORD ps3_texcoord_code[] =
20740 0xffff0300, /* ps_3_0 */
20741 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
20742 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
20743 0x0000ffff
20745 static const struct
20747 DWORD vs_version;
20748 const DWORD *vs;
20749 DWORD ps_version;
20750 const DWORD *ps;
20751 D3DCOLOR expected;
20752 BOOL allow_zero_alpha;
20753 BOOL partial;
20754 BOOL broken_warp;
20756 /* On AMD specular color is generally initialized to 0x00000000 and texcoords to 0xff000000
20757 * while on Nvidia it's the opposite. Just allow both.
20759 * Partially initialized varyings reliably handle the component that has been initialized.
20760 * The uninitialized components generally follow the rule above, with some exceptions on
20761 * radeon cards. r500 and r600 GPUs have been found to set uninitialized components to 0.0,
20762 * 0.5 and 1.0 without a sensible pattern. */
20763 tests[] =
20765 {D3DVS_VERSION(1, 1), vs1_code, 0, NULL, 0xffffffff},
20766 { 0, NULL, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff000000, TRUE},
20767 { 0, NULL, D3DPS_VERSION(2, 0), ps2_texcoord_code, 0xff000000, TRUE},
20768 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_diffuse_code, 0xffffffff},
20769 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_specular_code, 0xff000000, TRUE, FALSE, TRUE},
20770 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff000000, TRUE},
20771 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_diffuse_code, 0xffffffff},
20772 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_specular_code, 0xff000000, TRUE, FALSE, TRUE},
20773 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_texcoord_code, 0xff000000, TRUE},
20774 /* This test shows a lot of combinations of alpha and color that involve 1.0 and 0.0. Disable it.
20776 * AMD r500 sets alpha = 1.0, color = 0.0. Nvidia sets alpha = 1.0, color = 1.0. r600 Sets Alpha = 0.0,
20777 * color = 0.0. So far no combination with Alpha = 0.0, color = 1.0 has been found though.
20778 * {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_diffuse_code, 0xffffffff, FALSE, FALSE},
20780 * The same issues apply to the partially initialized COLOR0 varying, in addition to unreliable results
20781 * with partially initialized varyings in general.
20782 * {D3DVS_VERSION(3, 0), vs3_partial_code, D3DPS_VERSION(3, 0), ps3_diffuse_code, 0xff7fffff, TRUE, TRUE}, */
20783 {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_specular_code, 0xff000000, TRUE, FALSE, TRUE},
20784 {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_texcoord_code, 0xff000000, TRUE, FALSE, TRUE},
20785 {D3DVS_VERSION(1, 1), vs1_partial_code, 0, NULL, 0xff7fffff, FALSE, TRUE},
20786 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_diffuse_code, 0xff7fffff, FALSE, TRUE},
20787 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_specular_code, 0xff7f0000, TRUE, TRUE},
20788 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff7f0000, TRUE, TRUE},
20789 {D3DVS_VERSION(2, 0), vs2_partial_code, D3DPS_VERSION(2, 0), ps2_diffuse_code, 0xff7fffff, FALSE, TRUE},
20790 {D3DVS_VERSION(2, 0), vs2_partial_code, D3DPS_VERSION(2, 0), ps2_specular_code, 0xff7f0000, TRUE, TRUE},
20791 {D3DVS_VERSION(2, 0), vs2_partial_code, D3DPS_VERSION(2, 0), ps2_texcoord_code, 0xff7f0000, TRUE, TRUE},
20792 {D3DVS_VERSION(3, 0), vs3_partial_code, D3DPS_VERSION(3, 0), ps3_specular_code, 0x007f0000, FALSE, TRUE},
20793 {D3DVS_VERSION(3, 0), vs3_partial_code, D3DPS_VERSION(3, 0), ps3_texcoord_code, 0xff7f0000, TRUE, TRUE},
20795 IDirect3DDevice9 *device;
20796 IDirect3D9 *d3d;
20797 HWND window;
20798 HRESULT hr;
20799 D3DADAPTER_IDENTIFIER9 identifier;
20800 IDirect3DSurface9 *backbuffer;
20801 struct surface_readback rb;
20802 IDirect3DVertexShader9 *vs;
20803 IDirect3DPixelShader9 *ps;
20804 unsigned int i;
20805 ULONG refcount;
20806 D3DCAPS9 caps;
20807 D3DCOLOR color;
20808 BOOL warp;
20810 window = create_window();
20811 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20812 ok(!!d3d, "Failed to create a D3D object.\n");
20813 if (!(device = create_device(d3d, window, window, TRUE)))
20815 skip("Failed to create a D3D device, skipping tests.\n");
20816 IDirect3D9_Release(d3d);
20817 DestroyWindow(window);
20818 return;
20821 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
20822 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
20823 warp = adapter_is_warp(&identifier);
20825 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
20826 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
20828 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
20829 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
20831 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
20832 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
20833 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
20834 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
20835 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
20836 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
20837 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
20838 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
20839 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
20840 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
20841 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
20842 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
20843 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
20844 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#x.\n", hr);
20845 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
20846 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
20848 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
20849 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
20851 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
20853 if (caps.VertexShaderVersion < tests[i].vs_version
20854 || caps.PixelShaderVersion < tests[i].ps_version)
20856 skip("Vertex / pixel shader version not supported, skipping test %u.\n", i);
20857 continue;
20859 if (tests[i].vs)
20861 hr = IDirect3DDevice9_CreateVertexShader(device, tests[i].vs, &vs);
20862 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
20864 else
20866 vs = NULL;
20868 if (tests[i].ps)
20870 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].ps, &ps);
20871 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
20873 else
20875 ps = NULL;
20878 hr = IDirect3DDevice9_SetVertexShader(device, vs);
20879 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
20880 hr = IDirect3DDevice9_SetPixelShader(device, ps);
20881 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
20883 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
20884 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
20886 hr = IDirect3DDevice9_BeginScene(device);
20887 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
20889 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
20890 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20892 hr = IDirect3DDevice9_EndScene(device);
20893 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
20895 get_rt_readback(backbuffer, &rb);
20896 color = get_readback_color(&rb, 320, 240);
20897 ok(color_match(color, tests[i].expected, 1)
20898 || (tests[i].allow_zero_alpha && color_match(color, tests[i].expected & 0x00ffffff, 1))
20899 || (broken(warp && tests[i].broken_warp))
20900 || broken(tests[i].partial && color_match(color & 0x00ff0000, tests[i].expected & 0x00ff0000, 1)),
20901 "Got unexpected color 0x%08x, case %u.\n", color, i);
20902 release_surface_readback(&rb);
20904 if (vs)
20905 IDirect3DVertexShader9_Release(vs);
20906 if (ps)
20907 IDirect3DVertexShader9_Release(ps);
20910 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20911 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20913 IDirect3DSurface9_Release(backbuffer);
20914 refcount = IDirect3DDevice9_Release(device);
20915 ok(!refcount, "Device has %u references left.\n", refcount);
20916 IDirect3D9_Release(d3d);
20917 DestroyWindow(window);
20920 static void test_multisample_init(void)
20922 IDirect3DDevice9 *device;
20923 IDirect3D9 *d3d;
20924 IDirect3DSurface9 *back, *multi;
20925 ULONG refcount;
20926 HWND window;
20927 HRESULT hr;
20928 D3DCOLOR color;
20929 unsigned int x, y;
20930 struct surface_readback rb;
20931 BOOL all_zero = TRUE;
20933 window = create_window();
20934 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20935 ok(!!d3d, "Failed to create a D3D object.\n");
20937 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20938 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
20940 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample init test.\n");
20941 goto done;
20944 if (!(device = create_device(d3d, window, window, TRUE)))
20946 skip("Failed to create a D3D device, skipping tests.\n");
20947 goto done;
20950 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &back);
20951 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
20952 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
20953 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &multi, NULL);
20954 ok(SUCCEEDED(hr), "Failed to create multisampled render target, hr %#x.\n", hr);
20956 hr = IDirect3DDevice9_StretchRect(device, multi, NULL, back, NULL, D3DTEXF_POINT);
20957 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
20959 get_rt_readback(back, &rb);
20960 for (y = 0; y < 480; ++y)
20962 for (x = 0; x < 640; x++)
20964 color = get_readback_color(&rb, x, y);
20965 if (!color_match(color, 0x00000000, 0))
20967 all_zero = FALSE;
20968 break;
20971 if (!all_zero)
20972 break;
20974 release_surface_readback(&rb);
20975 ok(all_zero, "Got unexpected color 0x%08x, position %ux%u.\n", color, x, y);
20977 IDirect3DSurface9_Release(multi);
20978 IDirect3DSurface9_Release(back);
20980 refcount = IDirect3DDevice9_Release(device);
20981 ok(!refcount, "Device has %u references left.\n", refcount);
20983 done:
20984 IDirect3D9_Release(d3d);
20985 DestroyWindow(window);
20988 static void test_texture_blending(void)
20990 #define STATE_END() {0xffffffff, 0xffffffff}
20991 #define IS_STATE_END(s) (s.name == 0xffffffff && s.value == 0xffffffff)
20993 IDirect3DTexture9 *texture_bumpmap, *texture_red;
20994 IDirect3DSurface9 *backbuffer;
20995 struct surface_readback rb;
20996 D3DLOCKED_RECT locked_rect;
20997 IDirect3DDevice9 *device;
20998 unsigned int i, j, k;
20999 IDirect3D9 *d3d;
21000 D3DCOLOR color;
21001 ULONG refcount;
21002 D3DCAPS9 caps;
21003 HWND window;
21004 HRESULT hr;
21006 static const struct
21008 struct vec3 position;
21009 DWORD diffuse;
21011 quad[] =
21013 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
21014 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
21015 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
21016 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
21019 static const float bumpenvmat[4] = {1.0f, 1.0f, 0.0f, 0.0f};
21021 struct texture_stage_state
21023 D3DTEXTURESTAGESTATETYPE name;
21024 DWORD value;
21027 struct texture_stage
21029 enum
21031 TEXTURE_INVALID,
21032 TEXTURE_NONE,
21033 TEXTURE_BUMPMAP,
21034 TEXTURE_RED,
21036 texture;
21037 struct texture_stage_state state[20];
21040 static const struct texture_stage default_stage_state =
21042 TEXTURE_NONE,
21044 {D3DTSS_COLOROP, D3DTOP_DISABLE},
21045 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21046 {D3DTSS_COLORARG2, D3DTA_CURRENT},
21047 {D3DTSS_ALPHAOP, D3DTOP_DISABLE},
21048 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
21049 {D3DTSS_ALPHAARG2, D3DTA_CURRENT},
21050 {D3DTSS_BUMPENVMAT00, 0},
21051 {D3DTSS_BUMPENVMAT01, 0},
21052 {D3DTSS_BUMPENVMAT10, 0},
21053 {D3DTSS_BUMPENVMAT11, 0},
21054 {D3DTSS_BUMPENVLSCALE, 0},
21055 {D3DTSS_BUMPENVLOFFSET, 0},
21056 {D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE},
21057 {D3DTSS_COLORARG0, D3DTA_CURRENT},
21058 {D3DTSS_ALPHAARG0, D3DTA_CURRENT},
21059 {D3DTSS_RESULTARG, D3DTA_CURRENT},
21060 {D3DTSS_CONSTANT, 0},
21061 STATE_END(),
21065 const struct test
21067 DWORD tex_op_caps;
21068 D3DCOLOR expected_color;
21069 struct texture_stage stage[8];
21071 tests[] =
21074 D3DTEXOPCAPS_DISABLE,
21075 0x80ffff02,
21078 TEXTURE_NONE,
21080 STATE_END(),
21086 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
21087 0x80ffff02,
21090 TEXTURE_NONE,
21092 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21093 {D3DTSS_COLORARG1, D3DTA_CURRENT},
21094 STATE_END(),
21097 {TEXTURE_INVALID}
21101 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
21102 0x80ffff02,
21105 TEXTURE_NONE,
21107 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21108 {D3DTSS_COLORARG1, D3DTA_CURRENT},
21109 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21110 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21111 STATE_END(),
21117 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
21118 0x80ffff02,
21121 TEXTURE_NONE,
21123 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21124 {D3DTSS_COLORARG1, D3DTA_DIFFUSE},
21125 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21126 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
21127 STATE_END(),
21133 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
21134 0x00000000,
21137 TEXTURE_NONE,
21139 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21140 {D3DTSS_COLORARG1, D3DTA_TEMP},
21141 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21142 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21143 STATE_END(),
21149 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_SUBTRACT,
21150 0x80f0f000,
21153 TEXTURE_NONE,
21155 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21156 {D3DTSS_COLORARG1, D3DTA_CURRENT},
21157 STATE_END(),
21161 TEXTURE_NONE,
21163 {D3DTSS_COLOROP, D3DTOP_SUBTRACT},
21164 {D3DTSS_COLORARG1, D3DTA_CURRENT},
21165 {D3DTSS_COLORARG2, D3DTA_CONSTANT},
21166 {D3DTSS_CONSTANT, 0x0f0f0f0f},
21167 STATE_END(),
21170 {TEXTURE_INVALID}
21174 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_SUBTRACT,
21175 0x71f0f000,
21178 TEXTURE_NONE,
21180 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21181 {D3DTSS_COLORARG1, D3DTA_CURRENT},
21182 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21183 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21184 STATE_END(),
21188 TEXTURE_NONE,
21190 {D3DTSS_COLOROP, D3DTOP_SUBTRACT},
21191 {D3DTSS_COLORARG1, D3DTA_CURRENT},
21192 {D3DTSS_COLORARG2, D3DTA_CONSTANT},
21193 {D3DTSS_ALPHAOP, D3DTOP_SUBTRACT},
21194 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21195 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
21196 {D3DTSS_CONSTANT, 0x0f0f0f0f},
21197 STATE_END(),
21200 {TEXTURE_INVALID}
21205 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
21206 0x80ff0000,
21209 TEXTURE_BUMPMAP,
21211 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21212 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21213 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21214 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21215 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21216 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21217 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
21218 STATE_END(),
21223 TEXTURE_RED,
21225 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21226 STATE_END(),
21229 {TEXTURE_INVALID}
21233 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
21234 0x80ff0000,
21237 TEXTURE_BUMPMAP,
21239 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21240 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21241 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21242 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21243 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21244 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21245 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
21246 STATE_END(),
21250 TEXTURE_RED,
21252 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21253 STATE_END(),
21256 {TEXTURE_INVALID}
21260 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
21261 0x80ff0000,
21264 TEXTURE_BUMPMAP,
21266 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21267 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21268 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21269 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21270 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21271 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21272 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21273 STATE_END(),
21277 TEXTURE_RED,
21279 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21280 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21281 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21282 STATE_END(),
21285 {TEXTURE_INVALID}
21289 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
21290 0x00ff0000,
21293 TEXTURE_BUMPMAP,
21295 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21296 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21297 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21298 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21299 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21300 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21301 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21302 STATE_END(),
21306 TEXTURE_RED,
21308 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21309 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21310 {D3DTSS_COLORARG2, D3DTA_CURRENT},
21311 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21312 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21313 STATE_END(),
21316 {TEXTURE_INVALID}
21320 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
21321 0x80ff0000,
21324 TEXTURE_BUMPMAP,
21326 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21327 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21328 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21329 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21330 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21331 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21332 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21333 STATE_END(),
21337 TEXTURE_RED,
21339 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21340 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21341 {D3DTSS_COLORARG2, D3DTA_CURRENT},
21342 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21343 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21344 STATE_END(),
21347 {TEXTURE_INVALID}
21352 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
21353 | D3DTEXOPCAPS_ADD,
21354 0x80ff0000,
21357 TEXTURE_BUMPMAP,
21359 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21360 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21361 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21362 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21363 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21364 {D3DTSS_ALPHAOP, D3DTOP_ADD},
21365 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
21366 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
21367 {D3DTSS_CONSTANT, 0x0fffffff},
21368 STATE_END(),
21372 TEXTURE_RED,
21374 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21375 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21376 {D3DTSS_COLORARG2, D3DTA_CURRENT},
21377 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21378 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21379 STATE_END(),
21382 {TEXTURE_INVALID}
21386 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
21387 | D3DTEXOPCAPS_MODULATE2X,
21388 0x80ff0000,
21391 TEXTURE_BUMPMAP,
21393 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21394 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21395 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21396 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21397 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21398 {D3DTSS_ALPHAOP, D3DTOP_MODULATE2X},
21399 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
21400 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
21401 {D3DTSS_CONSTANT, 0x01ffffff},
21402 STATE_END(),
21406 TEXTURE_RED,
21408 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21409 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21410 {D3DTSS_COLORARG2, D3DTA_CURRENT},
21411 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21412 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21413 STATE_END(),
21416 {TEXTURE_INVALID}
21420 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
21421 | D3DTEXOPCAPS_MODULATE2X,
21422 0x80ffff00,
21425 TEXTURE_BUMPMAP,
21427 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21428 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21429 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21430 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21431 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21432 {D3DTSS_ALPHAOP, D3DTOP_MODULATE2X},
21433 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21434 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
21435 {D3DTSS_CONSTANT, 0x01ffffff},
21436 STATE_END(),
21440 TEXTURE_RED,
21442 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21443 {D3DTSS_COLORARG1, D3DTA_CURRENT},
21444 {D3DTSS_COLORARG2, D3DTA_CURRENT},
21445 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21446 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21447 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
21448 {D3DTSS_ALPHAARG0, D3DTA_CONSTANT},
21449 STATE_END(),
21452 {TEXTURE_INVALID}
21456 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
21457 0x01234567,
21460 TEXTURE_NONE,
21462 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21463 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
21464 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21465 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
21466 {D3DTSS_RESULTARG, D3DTA_TEMP},
21467 {D3DTSS_CONSTANT, 0x01234567},
21468 STATE_END(),
21472 TEXTURE_BUMPMAP,
21474 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21475 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21476 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21477 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21478 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21479 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21480 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21481 {D3DTSS_RESULTARG, D3DTA_TEMP},
21482 STATE_END(),
21486 TEXTURE_RED,
21488 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21489 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21490 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21491 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
21492 STATE_END(),
21496 TEXTURE_NONE,
21498 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21499 {D3DTSS_COLORARG1, D3DTA_TEMP},
21500 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21501 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21502 STATE_END(),
21505 {TEXTURE_INVALID}
21509 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
21510 0x00234567,
21513 TEXTURE_NONE,
21515 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21516 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
21517 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21518 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
21519 {D3DTSS_RESULTARG, D3DTA_TEMP},
21520 {D3DTSS_CONSTANT, 0x01234567},
21521 STATE_END(),
21525 TEXTURE_BUMPMAP,
21527 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21528 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21529 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21530 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21531 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21532 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21533 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21534 STATE_END(),
21538 TEXTURE_RED,
21540 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21541 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21542 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21543 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
21544 STATE_END(),
21548 TEXTURE_NONE,
21550 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21551 {D3DTSS_COLORARG1, D3DTA_TEMP},
21552 STATE_END(),
21555 {TEXTURE_INVALID}
21559 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
21560 0x01234567,
21563 TEXTURE_NONE,
21565 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21566 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
21567 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21568 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
21569 {D3DTSS_RESULTARG, D3DTA_TEMP},
21570 {D3DTSS_CONSTANT, 0x01234567},
21571 STATE_END(),
21575 TEXTURE_BUMPMAP,
21577 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21578 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21579 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21580 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21581 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21582 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21583 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21584 {D3DTSS_RESULTARG, D3DTA_TEMP},
21585 STATE_END(),
21589 TEXTURE_RED,
21591 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21592 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21593 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21594 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
21595 STATE_END(),
21599 TEXTURE_NONE,
21601 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21602 {D3DTSS_COLORARG1, D3DTA_TEMP},
21603 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21604 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21605 STATE_END(),
21608 {TEXTURE_INVALID}
21612 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
21613 0x01234567,
21616 TEXTURE_NONE,
21618 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21619 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
21620 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21621 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
21622 {D3DTSS_RESULTARG, D3DTA_CURRENT},
21623 {D3DTSS_CONSTANT, 0x01234567},
21624 STATE_END(),
21628 TEXTURE_BUMPMAP,
21630 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21631 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21632 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21633 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21634 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21635 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21636 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21637 {D3DTSS_RESULTARG, D3DTA_TEMP},
21638 STATE_END(),
21642 TEXTURE_RED,
21644 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21645 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21646 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21647 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
21648 {D3DTSS_RESULTARG, D3DTA_TEMP},
21649 STATE_END(),
21653 TEXTURE_NONE,
21655 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21656 {D3DTSS_COLORARG1, D3DTA_CURRENT},
21657 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21658 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21659 {D3DTSS_RESULTARG, D3DTA_CURRENT},
21660 STATE_END(),
21663 {TEXTURE_INVALID}
21668 window = create_window();
21669 d3d = Direct3DCreate9(D3D_SDK_VERSION);
21670 ok(!!d3d, "Failed to create a D3D object.\n");
21671 if (!(device = create_device(d3d, window, window, TRUE)))
21673 skip("Failed to create a D3D device.\n");
21674 goto done;
21677 memset(&caps, 0, sizeof(caps));
21678 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
21679 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr %#x.\n", hr);
21681 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
21683 skip("D3DPMISCCAPS_TSSARGTEMP not supported.\n");
21684 IDirect3DDevice9_Release(device);
21685 goto done;
21688 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_PERSTAGECONSTANT))
21690 skip("D3DPMISCCAPS_PERSTAGECONSTANT not supported.\n");
21691 IDirect3DDevice9_Release(device);
21692 goto done;
21695 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
21696 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_V8U8)))
21698 skip("D3DFMT_V8U8 not supported for legacy bump mapping.\n");
21699 IDirect3DDevice9_Release(device);
21700 goto done;
21703 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
21704 ok(hr == D3D_OK, "Can't get back buffer, hr %#x.\n", hr);
21706 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture_bumpmap, NULL);
21707 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr %#x.\n", hr);
21708 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture_red, NULL);
21709 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr %#x.\n", hr);
21711 memset(&locked_rect, 0, sizeof(locked_rect));
21712 hr = IDirect3DTexture9_LockRect(texture_bumpmap, 0, &locked_rect, NULL, 0);
21713 ok(SUCCEEDED(hr), "LockRect failed, hr %#x.\n", hr);
21714 *((WORD *)locked_rect.pBits) = 0xff00;
21715 hr = IDirect3DTexture9_UnlockRect(texture_bumpmap, 0);
21716 ok(SUCCEEDED(hr), "UnlockRect failed, hr %#x.\n", hr);
21718 memset(&locked_rect, 0, sizeof(locked_rect));
21719 hr = IDirect3DTexture9_LockRect(texture_red, 0, &locked_rect, NULL, 0);
21720 ok(SUCCEEDED(hr), "LockRect failed, hr %#x.\n", hr);
21721 *((DWORD *)locked_rect.pBits) = 0x00ff0000;
21722 hr = IDirect3DTexture9_UnlockRect(texture_red, 0);
21723 ok(SUCCEEDED(hr), "UnlockRect failed, hr %#x.\n", hr);
21725 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
21726 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
21727 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
21728 ok(hr == D3D_OK, "Failed to disable lighting, hr %#x.\n", hr);
21730 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
21732 const struct test *current_test = &tests[i];
21734 if ((caps.TextureOpCaps & current_test->tex_op_caps) != current_test->tex_op_caps)
21736 skip("Texture operations %#x not supported.\n", current_test->tex_op_caps);
21737 continue;
21740 for (j = 0; j < caps.MaxTextureBlendStages; ++j)
21742 IDirect3DTexture9 *current_texture = NULL;
21744 for (k = 0; !IS_STATE_END(default_stage_state.state[k]); ++k)
21746 hr = IDirect3DDevice9_SetTextureStageState(device, j,
21747 default_stage_state.state[k].name, default_stage_state.state[k].value);
21748 ok(SUCCEEDED(hr), "Test %u: SetTextureStageState failed, hr %#x.\n", i, hr);
21751 if (current_test->stage[j].texture != TEXTURE_INVALID)
21753 const struct texture_stage_state *current_state = current_test->stage[j].state;
21755 switch (current_test->stage[j].texture)
21757 case TEXTURE_RED:
21758 current_texture = texture_red;
21759 break;
21760 case TEXTURE_BUMPMAP:
21761 current_texture = texture_bumpmap;
21762 break;
21763 default:
21764 current_texture = NULL;
21765 break;
21768 for (k = 0; !IS_STATE_END(current_state[k]); ++k)
21770 hr = IDirect3DDevice9_SetTextureStageState(device, j,
21771 current_state[k].name, current_state[k].value);
21772 ok(SUCCEEDED(hr), "Test %u: SetTextureStageState failed, hr %#x.\n", i, hr);
21776 hr = IDirect3DDevice9_SetTexture(device, j, (IDirect3DBaseTexture9 *)current_texture);
21777 ok(SUCCEEDED(hr), "Test %u: SetTexture failed, hr %#x.\n", i, hr);
21780 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
21781 ok(hr == D3D_OK, "Test %u: IDirect3DDevice9_Clear failed, hr %#x.\n", i, hr);
21783 hr = IDirect3DDevice9_BeginScene(device);
21784 ok(SUCCEEDED(hr), "Test %u: BeginScene failed, hr %#x.\n", i, hr);
21785 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
21786 ok(SUCCEEDED(hr), "Test %u: DrawPrimitiveUP failed, hr %#x.\n", i, hr);
21787 hr = IDirect3DDevice9_EndScene(device);
21788 ok(SUCCEEDED(hr), "Test %u: EndScene failed, hr %#x.\n", i, hr);
21790 get_rt_readback(backbuffer, &rb);
21791 color = get_readback_color(&rb, 320, 240);
21792 ok(color_match(color, current_test->expected_color, 1),
21793 "Test %u: Got color 0x%08x, expected 0x%08x.\n", i, color, current_test->expected_color);
21794 release_surface_readback(&rb);
21795 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21796 ok(SUCCEEDED(hr), "Test %u: Present failed, hr %#x.\n", i, hr);
21799 IDirect3DTexture9_Release(texture_bumpmap);
21800 IDirect3DTexture9_Release(texture_red);
21801 IDirect3DSurface9_Release(backbuffer);
21802 refcount = IDirect3DDevice9_Release(device);
21803 ok(!refcount, "Device has %u references left.\n", refcount);
21804 done:
21805 IDirect3D9_Release(d3d);
21806 DestroyWindow(window);
21809 static void test_color_clamping(void)
21811 static const D3DMATRIX mat =
21813 1.0f, 0.0f, 0.0f, 0.0f,
21814 0.0f, 1.0f, 0.0f, 0.0f,
21815 0.0f, 0.0f, 1.0f, 0.0f,
21816 0.0f, 0.0f, 0.0f, 1.0f,
21817 }}};
21818 static const struct vec3 quad[] =
21820 {-1.0f, -1.0f, 0.1f},
21821 {-1.0f, 1.0f, 0.1f},
21822 { 1.0f, -1.0f, 0.1f},
21823 { 1.0f, 1.0f, 0.1f},
21825 static const DWORD vs1_code[] =
21827 0xfffe0101, /* vs_1_1 */
21828 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
21829 0x00000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
21830 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
21831 0x00000002, 0xd00f0000, 0xa0e40000, 0xa0e40000, /* add oD0, c0, c0 */
21832 0x00000002, 0xd00f0001, 0xa0e40000, 0xa0e40000, /* add oD1, c0, c0 */
21833 0x0000ffff
21835 static const DWORD vs2_code[] =
21837 0xfffe0200, /* vs_2_0 */
21838 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
21839 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
21840 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
21841 0x03000002, 0xd00f0000, 0xa0e40000, 0xa0e40000, /* add oD0, c0, c0 */
21842 0x03000002, 0xd00f0001, 0xa0e40000, 0xa0e40000, /* add oD1, c0, c0 */
21843 0x0000ffff
21845 static const DWORD vs3_code[] =
21847 0xfffe0300, /* vs_3_0 */
21848 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
21849 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
21850 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
21851 0x0200001f, 0x8001000a, 0xe00f0002, /* dcl_color1 o2 */
21852 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
21853 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
21854 0x03000002, 0xe00f0001, 0xa0e40000, 0xa0e40000, /* add o1, c0, c0 */
21855 0x03000002, 0xe00f0002, 0xa0e40000, 0xa0e40000, /* add o2, c0, c0 */
21856 0x0000ffff
21858 static const DWORD ps1_code[] =
21860 0xffff0101, /* ps_1_1 */
21861 0x00000051, 0xa00f0000, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000, /* def c0, 0.25, 0.25, 0.25, 0.25 */
21862 0x00000002, 0x800f0000, 0x90e40000, 0x90e40001, /* add r0, v0, v1 */
21863 0x00000005, 0x800f0000, 0x80e40000, 0xa0e40000, /* mul r0, r0, c0 */
21864 0x0000ffff
21866 static const DWORD ps2_code[] =
21868 0xffff0200, /* ps_2_0 */
21869 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
21870 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
21871 0x05000051, 0xa00f0000, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000, /* def c0, 0.25, 0.25, 0.25, 0.25 */
21872 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
21873 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
21874 0x03000005, 0x800f0000, 0x80e40000, 0xa0e40000, /* mul r0, r0, c0 */
21875 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
21876 0x0000ffff
21878 static const DWORD ps3_code[] =
21880 0xffff0300, /* ps_3_0 */
21881 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
21882 0x0200001f, 0x8001000a, 0x900f0001, /* dcl_color1 v1 */
21883 0x05000051, 0xa00f0000, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000, /* def c0, 0.25, 0.25, 0.25, 0.25 */
21884 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
21885 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
21886 0x03000005, 0x800f0800, 0x80e40000, 0xa0e40000, /* mul oC0, r0, c0 */
21887 0x0000ffff
21889 static const struct
21891 DWORD vs_version;
21892 const DWORD *vs;
21893 DWORD ps_version;
21894 const DWORD *ps;
21895 D3DCOLOR expected, broken;
21897 tests[] =
21899 {0, NULL, 0, NULL, 0x00404040},
21900 {0, NULL, D3DPS_VERSION(1, 1), ps1_code, 0x00404040, 0x00808080},
21901 {D3DVS_VERSION(1, 1), vs1_code, 0, NULL, 0x00404040},
21902 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_code, 0x007f7f7f},
21903 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_code, 0x007f7f7f},
21904 {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_code, 0x00ffffff},
21906 IDirect3DVertexShader9 *vs;
21907 IDirect3DPixelShader9 *ps;
21908 IDirect3DDevice9 *device;
21909 IDirect3D9 *d3d9;
21910 unsigned int i;
21911 ULONG refcount;
21912 D3DCOLOR color;
21913 D3DCAPS9 caps;
21914 HWND window;
21915 HRESULT hr;
21917 window = create_window();
21918 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
21919 ok(!!d3d9, "Failed to create a D3D object.\n");
21920 if (!(device = create_device(d3d9, window, window, TRUE)))
21922 skip("Failed to create a D3D device, skipping tests.\n");
21923 IDirect3D9_Release(d3d9);
21924 DestroyWindow(window);
21925 return;
21928 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
21929 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
21931 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
21932 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
21933 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
21934 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
21935 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
21936 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
21937 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
21938 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
21939 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
21940 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
21941 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
21942 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
21943 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
21944 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#x.\n", hr);
21945 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
21946 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
21947 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
21948 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
21950 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xff404040);
21951 ok(SUCCEEDED(hr), "Failed to set texture factor, hr %#x.\n", hr);
21952 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
21953 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
21954 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
21955 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
21956 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_SPECULAR);
21957 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
21958 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_MODULATE);
21959 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
21960 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
21961 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
21962 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
21963 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
21965 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
21966 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
21968 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
21970 if (caps.VertexShaderVersion < tests[i].vs_version
21971 || caps.PixelShaderVersion < tests[i].ps_version)
21973 skip("Vertex / pixel shader version not supported, skipping test %u.\n", i);
21974 continue;
21976 if (tests[i].vs)
21978 hr = IDirect3DDevice9_CreateVertexShader(device, tests[i].vs, &vs);
21979 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
21981 else
21983 vs = NULL;
21985 if (tests[i].ps)
21987 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].ps, &ps);
21988 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
21990 else
21992 ps = NULL;
21995 hr = IDirect3DDevice9_SetVertexShader(device, vs);
21996 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
21997 hr = IDirect3DDevice9_SetPixelShader(device, ps);
21998 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
22000 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
22001 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22003 hr = IDirect3DDevice9_BeginScene(device);
22004 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22006 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
22007 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22009 hr = IDirect3DDevice9_EndScene(device);
22010 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22012 color = getPixelColor(device, 320, 240);
22013 ok(color_match(color, tests[i].expected, 1) || broken(color_match(color, tests[i].broken, 1)),
22014 "Got unexpected color 0x%08x, case %u.\n", color, i);
22016 if (vs)
22017 IDirect3DVertexShader9_Release(vs);
22018 if (ps)
22019 IDirect3DVertexShader9_Release(ps);
22022 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
22023 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
22025 refcount = IDirect3DDevice9_Release(device);
22026 ok(!refcount, "Device has %u references left.\n", refcount);
22027 IDirect3D9_Release(d3d9);
22028 DestroyWindow(window);
22031 static void test_line_antialiasing_blending(void)
22033 IDirect3DDevice9 *device;
22034 IDirect3D9 *d3d9;
22035 ULONG refcount;
22036 D3DCOLOR color;
22037 D3DCAPS9 caps;
22038 HWND window;
22039 HRESULT hr;
22041 static const struct
22043 struct vec3 position;
22044 DWORD diffuse;
22046 green_quad[] =
22048 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
22049 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
22050 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
22051 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
22053 static const struct
22055 struct vec3 position;
22056 DWORD diffuse;
22058 red_quad[] =
22060 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
22061 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
22062 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
22063 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
22066 window = create_window();
22067 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
22068 ok(!!d3d9, "Failed to create a D3D object.\n");
22069 if (!(device = create_device(d3d9, window, window, TRUE)))
22071 skip("Failed to create a D3D device.\n");
22072 IDirect3D9_Release(d3d9);
22073 DestroyWindow(window);
22074 return;
22077 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
22078 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
22079 trace("Line antialiasing support: %#x.\n", caps.LineCaps & D3DLINECAPS_ANTIALIAS);
22081 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
22082 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
22083 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
22084 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
22085 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
22086 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
22088 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
22089 ok(SUCCEEDED(hr), "Failed to enable blending, hr %#x.\n", hr);
22090 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_BLENDOP, D3DBLENDOP_ADD);
22091 ok(SUCCEEDED(hr), "Failed to set blend op, hr %#x.\n", hr);
22092 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
22093 ok(SUCCEEDED(hr), "Failed to set src blend, hr %#x.\n", hr);
22094 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_DESTALPHA);
22095 ok(SUCCEEDED(hr), "Failed to set dest blend, hr %#x.\n", hr);
22097 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
22098 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
22099 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
22100 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
22101 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
22102 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#x.\n", hr);
22103 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
22104 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#x.\n", hr);
22106 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
22107 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
22109 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
22110 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22111 hr = IDirect3DDevice9_BeginScene(device);
22112 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22113 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
22114 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22115 hr = IDirect3DDevice9_EndScene(device);
22116 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22117 color = getPixelColor(device, 320, 240);
22118 ok(color_match(color, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color);
22120 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
22121 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22122 hr = IDirect3DDevice9_BeginScene(device);
22123 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22124 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
22125 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22126 hr = IDirect3DDevice9_EndScene(device);
22127 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22128 color = getPixelColor(device, 320, 240);
22129 ok(color_match(color, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color);
22131 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
22132 ok(SUCCEEDED(hr), "Failed to disable blending, hr %#x.\n", hr);
22134 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
22135 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22136 hr = IDirect3DDevice9_BeginScene(device);
22137 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22138 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
22139 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22140 hr = IDirect3DDevice9_EndScene(device);
22141 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22142 color = getPixelColor(device, 320, 240);
22143 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
22145 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
22146 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22147 hr = IDirect3DDevice9_BeginScene(device);
22148 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22149 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
22150 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22151 hr = IDirect3DDevice9_EndScene(device);
22152 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22153 color = getPixelColor(device, 320, 240);
22154 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
22156 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ANTIALIASEDLINEENABLE, TRUE);
22157 ok(SUCCEEDED(hr), "Failed to enable line antialiasing, hr %#x.\n", hr);
22159 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
22160 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22161 hr = IDirect3DDevice9_BeginScene(device);
22162 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22163 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
22164 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22165 hr = IDirect3DDevice9_EndScene(device);
22166 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22167 color = getPixelColor(device, 320, 240);
22168 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
22170 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
22171 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22172 hr = IDirect3DDevice9_BeginScene(device);
22173 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22174 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
22175 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22176 hr = IDirect3DDevice9_EndScene(device);
22177 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22178 color = getPixelColor(device, 320, 240);
22179 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
22181 refcount = IDirect3DDevice9_Release(device);
22182 ok(!refcount, "Device has %u references left.\n", refcount);
22183 IDirect3D9_Release(d3d9);
22184 DestroyWindow(window);
22187 static void test_dsy(void)
22189 static const DWORD vs_code[] =
22191 0xfffe0300, /* vs_3_0 */
22192 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
22193 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
22194 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
22195 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
22196 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
22197 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
22198 0x0000ffff
22200 static const DWORD ps_code[] =
22202 0xffff0300, /* ps_3_0 */
22203 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
22204 0x05000051, 0xa00f0000, 0x43700000, 0x3f000000, 0x00000000, 0x00000000, /* def c0, 240.0, 0.5, 0.0, 0.0 */
22205 0x0200005c, 0x800f0000, 0x90e40000, /* dsy r0, v0 */
22206 0x03000005, 0x800f0000, 0x80e40000, 0xa0000000, /* mul r0, r0, c0.x */
22207 0x03000002, 0x800f0800, 0x80e40000, 0xa0550000, /* add oC0, r0, c0.y */
22208 0x0000ffff
22210 static const struct
22212 struct vec3 pos;
22213 D3DCOLOR color;
22215 quad[] =
22217 {{-1.0f, -1.0f, 0.1f}, 0x00ff0000},
22218 {{-1.0f, 1.0f, 0.1f}, 0x0000ff00},
22219 {{ 1.0f, -1.0f, 0.1f}, 0x00ff0000},
22220 {{ 1.0f, 1.0f, 0.1f}, 0x0000ff00},
22222 IDirect3DSurface9 *backbuffer, *rt;
22223 IDirect3DVertexShader9 *vs;
22224 IDirect3DPixelShader9 *ps;
22225 IDirect3DDevice9 *device;
22226 IDirect3D9 *d3d;
22227 ULONG refcount;
22228 D3DCAPS9 caps;
22229 DWORD color;
22230 HWND window;
22231 HRESULT hr;
22233 window = create_window();
22234 d3d = Direct3DCreate9(D3D_SDK_VERSION);
22235 ok(!!d3d, "Failed to create a D3D object.\n");
22236 if (!(device = create_device(d3d, window, window, TRUE)))
22238 skip("Failed to create a D3D device, skipping tests.\n");
22239 goto done;
22242 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
22243 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
22244 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
22246 skip("No ps_3_0 support, skipping dsy tests.\n");
22247 IDirect3DDevice9_Release(device);
22248 goto done;
22251 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
22252 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
22254 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
22255 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
22256 ok(SUCCEEDED(hr), "Failed to create offscreen render target, hr %#x.\n", hr);
22257 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
22258 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
22260 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
22261 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
22262 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
22263 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
22265 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
22266 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
22267 hr = IDirect3DDevice9_SetVertexShader(device, vs);
22268 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
22269 hr = IDirect3DDevice9_SetPixelShader(device, ps);
22270 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
22272 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
22273 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22274 hr = IDirect3DDevice9_BeginScene(device);
22275 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22276 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
22277 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
22278 hr = IDirect3DDevice9_EndScene(device);
22279 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22281 color = getPixelColor(device, 360, 240);
22282 ok(color_match(color, 0x00ff007f, 1), "Got unexpected color 0x%08x.\n", color);
22284 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
22285 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
22287 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
22288 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22289 hr = IDirect3DDevice9_BeginScene(device);
22290 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22291 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
22292 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
22293 hr = IDirect3DDevice9_EndScene(device);
22294 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22296 color = getPixelColor(device, 360, 240);
22297 ok(color_match(color, 0x00ff007f, 1), "Got unexpected color 0x%08x.\n", color);
22299 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
22300 ok(SUCCEEDED(hr), "Failed to present frame, hr %#x.\n", hr);
22302 IDirect3DSurface9_Release(rt);
22303 IDirect3DSurface9_Release(backbuffer);
22304 IDirect3DVertexShader9_Release(vs);
22305 IDirect3DPixelShader9_Release(ps);
22307 refcount = IDirect3DDevice9_Release(device);
22308 ok(!refcount, "Device has %u references left.\n", refcount);
22309 done:
22310 IDirect3D9_Release(d3d);
22311 DestroyWindow(window);
22314 static void test_evict_bound_resources(void)
22316 IDirect3DVertexBuffer9 *vb;
22317 IDirect3DIndexBuffer9 *ib;
22318 IDirect3DDevice9 *device;
22319 IDirect3D9 *d3d9;
22320 ULONG refcount;
22321 D3DCOLOR color;
22322 HWND window;
22323 void *data;
22324 HRESULT hr;
22326 static const struct
22328 struct vec3 position;
22329 DWORD diffuse;
22331 green_quad[] =
22333 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
22334 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
22335 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
22336 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
22338 static const unsigned short indices[] = {0, 1, 2, 3, 2, 1};
22340 window = create_window();
22341 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
22342 ok(!!d3d9, "Failed to create a D3D object.\n");
22344 if (!(device = create_device(d3d9, window, window, TRUE)))
22346 skip("Failed to create a D3D device.\n");
22347 IDirect3D9_Release(d3d9);
22348 DestroyWindow(window);
22349 return;
22352 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0,
22353 D3DFMT_INDEX16, D3DPOOL_MANAGED, &ib, NULL);
22354 ok(SUCCEEDED(hr), "Failed to create index buffer, hr %#x.\n", hr);
22356 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(green_quad), 0,
22357 D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &vb, NULL);
22358 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
22360 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
22361 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
22362 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
22363 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
22364 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
22365 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
22367 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
22368 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
22370 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(green_quad), &data, 0);
22371 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#x.\n", hr);
22372 memcpy(data, green_quad, sizeof(green_quad));
22373 hr = IDirect3DVertexBuffer9_Unlock(vb);
22374 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#x.\n", hr);
22376 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), &data, 0);
22377 ok(hr == D3D_OK, "Failed to lock index buffer, hr %#x.\n", hr);
22378 memcpy(data, indices, sizeof(indices));
22379 hr = IDirect3DIndexBuffer9_Unlock(ib);
22380 ok(hr == D3D_OK, "Failed to unlock index buffer, hr %#x.\n", hr);
22382 hr = IDirect3DDevice9_SetIndices(device, ib);
22383 ok(hr == D3D_OK, "Failed to set index buffer, hr %#x.\n", hr);
22384 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(*green_quad));
22385 ok(hr == D3D_OK, "Failed to set stream source, hr %#x.\n", hr);
22387 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
22388 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22389 hr = IDirect3DDevice9_BeginScene(device);
22390 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22391 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
22392 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22393 hr = IDirect3DDevice9_EndScene(device);
22394 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22395 color = getPixelColor(device, 320, 240);
22396 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
22398 hr = IDirect3DDevice9_EvictManagedResources(device);
22399 ok(hr == D3D_OK, "Failed to evict managed resources, hr %#x.\n", hr);
22401 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
22402 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22403 hr = IDirect3DDevice9_BeginScene(device);
22404 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22405 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
22406 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22407 hr = IDirect3DDevice9_EndScene(device);
22408 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22409 color = getPixelColor(device, 320, 240);
22410 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
22412 IDirect3DIndexBuffer9_Release(ib);
22413 IDirect3DVertexBuffer9_Release(vb);
22414 refcount = IDirect3DDevice9_Release(device);
22415 ok(!refcount, "Device has %u references left.\n", refcount);
22416 IDirect3D9_Release(d3d9);
22417 DestroyWindow(window);
22420 /* This test shows that 0xffff is valid index in D3D9. */
22421 static void test_max_index16(void)
22423 static const struct vertex
22425 struct vec3 position;
22426 DWORD diffuse;
22428 green_quad[] =
22430 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22431 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22432 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22433 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22435 static const unsigned short indices[] = {0, 1, 2, 0xffff};
22436 static const unsigned int vertex_count = 0xffff + 1;
22438 D3DADAPTER_IDENTIFIER9 identifier;
22439 IDirect3DVertexBuffer9 *vb;
22440 IDirect3DIndexBuffer9 *ib;
22441 IDirect3DDevice9 *device;
22442 struct vertex *vb_data;
22443 IDirect3D9 *d3d9;
22444 ULONG refcount;
22445 D3DCOLOR color;
22446 D3DCAPS9 caps;
22447 HWND window;
22448 void *data;
22449 HRESULT hr;
22450 BOOL warp;
22452 window = create_window();
22453 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
22454 ok(!!d3d9, "Failed to create a D3D object.\n");
22456 hr = IDirect3D9_GetAdapterIdentifier(d3d9, D3DADAPTER_DEFAULT, 0, &identifier);
22457 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
22458 warp = adapter_is_warp(&identifier);
22460 if (!(device = create_device(d3d9, window, window, TRUE)))
22462 skip("Failed to create a D3D device.\n");
22463 IDirect3D9_Release(d3d9);
22464 DestroyWindow(window);
22465 return;
22468 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
22469 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
22470 if (caps.MaxVertexIndex < 0xffff)
22472 skip("Max vertex index is lower than 0xffff (%#x).\n", caps.MaxVertexIndex);
22473 IDirect3DDevice9_Release(device);
22474 IDirect3D9_Release(d3d9);
22475 DestroyWindow(window);
22476 return;
22479 hr = IDirect3DDevice9_CreateVertexBuffer(device, vertex_count * sizeof(*green_quad), 0,
22480 D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &vb, NULL);
22481 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
22483 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0,
22484 D3DFMT_INDEX16, D3DPOOL_MANAGED, &ib, NULL);
22485 ok(SUCCEEDED(hr), "Failed to create index buffer, hr %#x.\n", hr);
22487 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
22488 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
22489 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
22490 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
22491 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
22492 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
22494 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
22495 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
22497 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(green_quad), (void **)&vb_data, 0);
22498 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#x.\n", hr);
22499 vb_data[0] = green_quad[0];
22500 vb_data[1] = green_quad[1];
22501 vb_data[2] = green_quad[2];
22502 vb_data[0xffff] = green_quad[3];
22503 hr = IDirect3DVertexBuffer9_Unlock(vb);
22504 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#x.\n", hr);
22506 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), &data, 0);
22507 ok(hr == D3D_OK, "Failed to lock index buffer, hr %#x.\n", hr);
22508 memcpy(data, indices, sizeof(indices));
22509 hr = IDirect3DIndexBuffer9_Unlock(ib);
22510 ok(hr == D3D_OK, "Failed to unlock index buffer, hr %#x.\n", hr);
22512 hr = IDirect3DDevice9_SetIndices(device, ib);
22513 ok(hr == D3D_OK, "Failed to set index buffer, hr %#x.\n", hr);
22514 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(struct vertex));
22515 ok(hr == D3D_OK, "Failed to set stream source, hr %#x.\n", hr);
22517 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
22518 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22519 hr = IDirect3DDevice9_BeginScene(device);
22520 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22521 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 0, vertex_count, 0, 2);
22522 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22523 hr = IDirect3DDevice9_EndScene(device);
22524 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22525 color = getPixelColor(device, 20, 20);
22526 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
22527 color = getPixelColor(device, 320, 240);
22528 ok(color_match(color, 0x0000ff00, 1) || broken(warp), "Got unexpected color 0x%08x.\n", color);
22529 color = getPixelColor(device, 620, 460);
22530 ok(color_match(color, 0x0000ff00, 1) || broken(warp), "Got unexpected color 0x%08x.\n", color);
22532 IDirect3DIndexBuffer9_Release(ib);
22533 IDirect3DVertexBuffer9_Release(vb);
22534 refcount = IDirect3DDevice9_Release(device);
22535 ok(!refcount, "Device has %u references left.\n", refcount);
22536 IDirect3D9_Release(d3d9);
22537 DestroyWindow(window);
22540 static void test_backbuffer_resize(void)
22542 D3DPRESENT_PARAMETERS present_parameters = {0};
22543 IDirect3DSurface9 *backbuffer;
22544 IDirect3DDevice9 *device;
22545 IDirect3D9 *d3d;
22546 D3DCOLOR color;
22547 ULONG refcount;
22548 HWND window;
22549 HRESULT hr;
22551 static const struct
22553 struct vec3 position;
22554 DWORD diffuse;
22556 quad[] =
22558 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22559 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22560 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22561 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22564 window = create_window();
22565 d3d = Direct3DCreate9(D3D_SDK_VERSION);
22566 ok(!!d3d, "Failed to create a D3D object.\n");
22567 if (!(device = create_device(d3d, window, window, TRUE)))
22569 skip("Failed to create a D3D device.\n");
22570 goto done;
22573 /* Wine d3d9 implementation had a bug which was triggered by a
22574 * SetRenderTarget() call with an unreferenced surface. */
22575 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
22576 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
22577 refcount = IDirect3DSurface9_Release(backbuffer);
22578 ok(!refcount, "Surface has %u references left.\n", refcount);
22579 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
22580 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
22581 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
22582 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
22584 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
22585 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22586 color = getPixelColor(device, 1, 1);
22587 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
22589 present_parameters.BackBufferWidth = 800;
22590 present_parameters.BackBufferHeight = 600;
22591 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
22592 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
22593 present_parameters.hDeviceWindow = NULL;
22594 present_parameters.Windowed = TRUE;
22595 present_parameters.EnableAutoDepthStencil = TRUE;
22596 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
22597 hr = IDirect3DDevice9_Reset(device, &present_parameters);
22598 ok(SUCCEEDED(hr), "Failed to reset, hr %#x.\n", hr);
22600 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
22601 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
22602 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
22603 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
22604 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
22605 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
22606 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
22607 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
22609 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
22610 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
22611 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
22612 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
22613 IDirect3DSurface9_Release(backbuffer);
22615 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
22616 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22617 color = getPixelColor(device, 1, 1);
22618 ok(color == 0x00ffff00, "Got unexpected color 0x%08x.\n", color);
22619 color = getPixelColor(device, 700, 500);
22620 ok(color == 0x00ffff00, "Got unexpected color 0x%08x.\n", color);
22622 hr = IDirect3DDevice9_BeginScene(device);
22623 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22624 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
22625 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22626 hr = IDirect3DDevice9_EndScene(device);
22627 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22628 color = getPixelColor(device, 1, 1);
22629 ok(color == 0x0000ff00, "Got unexpected color 0x%08x.\n", color);
22630 color = getPixelColor(device, 700, 500);
22631 ok(color == 0x0000ff00, "Got unexpected color 0x%08x.\n", color);
22633 refcount = IDirect3DDevice9_Release(device);
22634 ok(!refcount, "Device has %u references left.\n", refcount);
22635 done:
22636 IDirect3D9_Release(d3d);
22637 DestroyWindow(window);
22640 static void test_drawindexedprimitiveup(void)
22642 static const struct vertex
22644 struct vec3 position;
22645 DWORD diffuse;
22647 quad[] =
22649 {{-1.0f, -1.0f, 0.1f}, 0xff00ff00},
22650 {{-1.0f, 1.0f, 0.1f}, 0xff0000ff},
22651 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
22652 {{ 1.0f, 1.0f, 0.1f}, 0xff0000ff},
22654 {{-1.0f, -1.0f, 0.1f}, 0xff0000ff},
22655 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
22656 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
22657 {{ 1.0f, 1.0f, 0.1f}, 0xff00ff00},
22659 static const unsigned short indices[] = {0, 1, 2, 3, 4, 5, 6, 7};
22660 IDirect3DDevice9 *device;
22661 IDirect3D9 *d3d;
22662 ULONG refcount;
22663 D3DCOLOR color;
22664 HWND window;
22665 HRESULT hr;
22667 window = create_window();
22668 d3d = Direct3DCreate9(D3D_SDK_VERSION);
22669 ok(!!d3d, "Failed to create a D3D object.\n");
22671 if (!(device = create_device(d3d, window, window, TRUE)))
22673 skip("Failed to create a D3D device.\n");
22674 IDirect3D9_Release(d3d);
22675 DestroyWindow(window);
22676 return;
22679 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
22680 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
22681 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
22682 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
22683 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
22684 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
22686 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
22687 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
22689 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
22690 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22692 hr = IDirect3DDevice9_BeginScene(device);
22693 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22694 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 4, 4, 2, indices + 4, D3DFMT_INDEX16, quad, sizeof(*quad));
22695 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22696 hr = IDirect3DDevice9_EndScene(device);
22697 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22699 color = getPixelColor(device, 160, 120);
22700 ok(color_match(color, 0x0040bf00, 1), "Got unexpected color 0x%08x.\n", color);
22701 color = getPixelColor(device, 480, 120);
22702 ok(color_match(color, 0x0040bf00, 1), "Got unexpected color 0x%08x.\n", color);
22703 color = getPixelColor(device, 160, 360);
22704 ok(color_match(color, 0x00404080, 1), "Got unexpected color 0x%08x.\n", color);
22705 color = getPixelColor(device, 480, 360);
22706 ok(color_match(color, 0x00bf4000, 1), "Got unexpected color 0x%08x.\n", color);
22708 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
22709 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22711 hr = IDirect3DDevice9_BeginScene(device);
22712 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22713 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 0, 4, 2, indices, D3DFMT_INDEX16, quad, sizeof(*quad));
22714 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22715 hr = IDirect3DDevice9_EndScene(device);
22716 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22718 color = getPixelColor(device, 160, 120);
22719 ok(color_match(color, 0x004000bf, 1), "Got unexpected color 0x%08x.\n", color);
22720 color = getPixelColor(device, 480, 120);
22721 ok(color_match(color, 0x004000bf, 1), "Got unexpected color 0x%08x.\n", color);
22722 color = getPixelColor(device, 160, 360);
22723 ok(color_match(color, 0x00408040, 1), "Got unexpected color 0x%08x.\n", color);
22724 color = getPixelColor(device, 480, 360);
22725 ok(color_match(color, 0x00bf0040, 1), "Got unexpected color 0x%08x.\n", color);
22727 refcount = IDirect3DDevice9_Release(device);
22728 ok(!refcount, "Device has %u references left.\n", refcount);
22729 IDirect3D9_Release(d3d);
22730 DestroyWindow(window);
22733 static void test_vertex_texture(void)
22735 static const D3DVERTEXELEMENT9 decl_elements[] =
22737 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
22738 D3DDECL_END()
22740 static const struct vec3 quad[] =
22742 {-1.0f, -1.0f, 0.0f},
22743 {-1.0f, 1.0f, 0.0f},
22744 { 1.0f, -1.0f, 0.0f},
22745 { 1.0f, 1.0f, 0.0f},
22747 static const DWORD vs_code[] =
22749 0xfffe0300, /* vs_3_0 */
22750 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0, 0, 0, 0 */
22751 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
22752 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
22753 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
22754 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
22755 0x0300005f, 0xe00f0001, 0xa0000000, 0xa0e40800, /* texldl o1, c0.x, s0 */
22756 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
22757 0x0000ffff, /* end */
22759 static const DWORD ps_code[] =
22761 0xffff0300, /* ps_3_0 */
22762 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color v0 */
22763 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
22764 0x0000ffff, /* end */
22766 static const DWORD texture_data[4] = {0x00ffff00, 0x00ffff00, 0x00ffff00, 0x00ffff00};
22767 IDirect3DVertexDeclaration9 *declaration;
22768 IDirect3DTexture9 *texture;
22769 IDirect3DVertexShader9 *vs;
22770 IDirect3DPixelShader9 *ps;
22771 IDirect3DDevice9 *device;
22772 D3DLOCKED_RECT lr;
22773 IDirect3D9 *d3d;
22774 D3DCOLOR color;
22775 ULONG refcount;
22776 D3DCAPS9 caps;
22777 HWND window;
22778 HRESULT hr;
22780 window = create_window();
22781 d3d = Direct3DCreate9(D3D_SDK_VERSION);
22782 ok(!!d3d, "Failed to create D3D object.\n");
22784 if (!(device = create_device(d3d, window, window, TRUE)))
22786 skip("Failed to create D3D device.\n");
22787 IDirect3D9_Release(d3d);
22788 DestroyWindow(window);
22789 return;
22792 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
22793 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
22794 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0) || caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
22796 skip("SM3 is not supported.\n");
22797 goto done;
22799 if (!(caps.VertexTextureFilterCaps & D3DPTFILTERCAPS_MAGFPOINT)
22800 || !(caps.VertexTextureFilterCaps & D3DPTFILTERCAPS_MINFPOINT))
22802 skip("Vertex texture point filtering is not supported, caps %#x.\n", caps.VertexTextureFilterCaps);
22803 goto done;
22805 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
22806 D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8);
22807 if (hr != D3D_OK)
22809 skip("No vertex texture fetch support for D3DFMT_A8R8G8B8, hr %#x.\n", hr);
22810 goto done;
22813 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
22814 ok(hr == D3D_OK, "Failed to create texture, hr %#x.\n", hr);
22815 memset(&lr, 0, sizeof(lr));
22816 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
22817 ok(hr == D3D_OK, "Failed to lock texture, hr %#x.\n", hr);
22818 memcpy(lr.pBits, texture_data, sizeof(texture_data));
22819 hr = IDirect3DTexture9_UnlockRect(texture, 0);
22820 ok(hr == D3D_OK, "Failed to unlock texture, hr %#x.\n", hr);
22822 hr = IDirect3DDevice9_SetTexture(device, D3DVERTEXTEXTURESAMPLER0, (IDirect3DBaseTexture9 *)texture);
22823 ok(hr == D3D_OK, "Failed to set texture, hr %#x.\n", hr);
22825 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &declaration);
22826 ok(SUCCEEDED(hr), "Failed to create vertex declaration, hr %#x.\n", hr);
22827 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
22828 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
22829 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
22830 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
22832 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration);
22833 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
22834 hr = IDirect3DDevice9_SetVertexShader(device, vs);
22835 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
22836 hr = IDirect3DDevice9_SetPixelShader(device, ps);
22837 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
22839 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
22840 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22841 hr = IDirect3DDevice9_BeginScene(device);
22842 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22843 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
22844 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22845 hr = IDirect3DDevice9_EndScene(device);
22846 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22847 color = getPixelColor(device, 160, 360);
22848 ok(color == texture_data[0], "Got unexpected color 0x%08x.\n", color);
22850 IDirect3DPixelShader9_Release(ps);
22851 IDirect3DVertexShader9_Release(vs);
22852 IDirect3DTexture9_Release(texture);
22853 IDirect3DVertexDeclaration9_Release(declaration);
22854 done:
22855 refcount = IDirect3DDevice9_Release(device);
22856 ok(!refcount, "Device has %u references left.\n", refcount);
22857 IDirect3D9_Release(d3d);
22858 DestroyWindow(window);
22861 static void test_mvp_software_vertex_shaders(void)
22863 IDirect3DVertexDeclaration9 *vertex_declaration;
22864 D3DPRESENT_PARAMETERS present_parameters = {0};
22865 IDirect3DVertexShader9 *pure_sw_shader = NULL;
22866 IDirect3DVertexShader9 *reladdr_shader = NULL;
22867 IDirect3DDevice9 *device;
22868 DWORD expected_color;
22869 IDirect3D9 *d3d;
22870 ULONG refcount;
22871 D3DCAPS9 caps;
22872 DWORD color;
22873 HWND window;
22874 HRESULT hr;
22876 static const float c_index[4] = {256.0f, 0.0f, 0.0f, 0.0f};
22877 static const float c_color[4] = {0.0f, 1.0f, 0.0f, 1.0f};
22878 static const DWORD reladdr_shader_code[] =
22880 0xfffe0200, /* vs_2_0 */
22881 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
22882 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c1, 1.0, 1.0, 1.0, 1.0 */
22883 0x0200002e, 0xb0010000, 0xa0000000, /* mova a0.x, c0.x */
22884 0x03000001, 0xd00f0000, 0xa0e42000, 0xb0000000, /* mov oD0, c[a0.x] */
22885 0x02000001, 0xd0040000, 0xa0e40001, /* mov oD0.z, c1 */
22886 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
22887 0x0000ffff /* END */
22889 static const DWORD pure_sw_shader_code[] =
22891 0xfffe0200, /* vs_2_0 */
22892 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
22893 0x05000051, 0xa00f0100, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c256, 1.0, 1.0, 1.0, 1.0 */
22894 0x02000001, 0xd00f0000, 0xa0e40100, /* mov oD0, c256 */
22895 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
22896 0x0000ffff /* END */
22899 static const struct
22901 float position[3];
22902 DWORD color;
22904 quad[] =
22906 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
22907 {{-1.0f, 1.0f, 0.0f}, 0xffff0000},
22908 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000},
22909 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
22911 static const D3DVERTEXELEMENT9 decl_elements[] =
22913 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
22914 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
22915 D3DDECL_END()
22918 window = create_window();
22919 d3d = Direct3DCreate9(D3D_SDK_VERSION);
22920 ok(!!d3d, "Failed to create a D3D object.\n");
22922 present_parameters.Windowed = TRUE;
22923 present_parameters.hDeviceWindow = window;
22924 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
22925 present_parameters.BackBufferWidth = 640;
22926 present_parameters.BackBufferHeight = 480;
22927 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
22928 present_parameters.EnableAutoDepthStencil = TRUE;
22929 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
22931 if (FAILED(IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
22932 D3DCREATE_MIXED_VERTEXPROCESSING, &present_parameters, &device)))
22934 skip("Failed to create a D3D device, skipping tests.\n");
22935 goto done;
22938 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
22939 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
22940 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
22942 skip("No vs_2_0 support, skipping tests.\n");
22943 IDirect3DDevice9_Release(device);
22944 goto done;
22947 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
22948 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
22950 hr = IDirect3DDevice9_SetSoftwareVertexProcessing(device, 0);
22951 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22953 hr = IDirect3DDevice9_CreateVertexShader(device, reladdr_shader_code, &reladdr_shader);
22954 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22955 hr = IDirect3DDevice9_CreateVertexShader(device, pure_sw_shader_code, &pure_sw_shader);
22956 todo_wine
22957 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22958 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
22959 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22960 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
22961 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22963 hr = IDirect3DDevice9_SetVertexShader(device, pure_sw_shader);
22964 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22966 hr = IDirect3DDevice9_BeginScene(device);
22967 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22968 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
22969 todo_wine
22970 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
22971 hr = IDirect3DDevice9_EndScene(device);
22972 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22974 expected_color = 0; /* Nothing rendered. */
22975 color = getPixelColor(device, 5, 5);
22976 todo_wine
22977 ok(color == expected_color, "Expected color 0x%08x, got 0x%08x (sw shader in hw mode).\n",
22978 expected_color, color);
22980 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
22981 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22982 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
22983 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22985 hr = IDirect3DDevice9_BeginScene(device);
22986 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22987 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
22988 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22989 hr = IDirect3DDevice9_EndScene(device);
22990 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22992 expected_color = 0x00ff0000; /* Color from vertex data and not from the shader. */
22993 color = getPixelColor(device, 5, 5);
22994 ok(color == expected_color, "Expected color 0x%08x, got 0x%08x (sw shader in hw mode, second attempt).\n",
22995 expected_color, color);
22997 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
22998 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22999 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
23000 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
23002 hr = IDirect3DDevice9_BeginScene(device);
23003 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
23004 hr = IDirect3DDevice9_SetSoftwareVertexProcessing(device, 1);
23005 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
23006 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
23007 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
23008 hr = IDirect3DDevice9_EndScene(device);
23009 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
23011 expected_color = 0x00ffffff;
23012 color = getPixelColor(device, 5, 5);
23013 todo_wine
23014 ok(color == expected_color, "Expected color 0x%08x, got 0x%08x (sw shader in sw mode).\n",
23015 expected_color, color);
23017 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
23018 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
23019 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
23020 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
23022 hr = IDirect3DDevice9_SetSoftwareVertexProcessing(device, 0);
23023 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
23024 hr = IDirect3DDevice9_SetVertexShader(device, reladdr_shader);
23025 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
23027 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, c_index, 1);
23028 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
23029 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, (unsigned int)c_index[0], c_color, 1);
23030 todo_wine
23031 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
23033 hr = IDirect3DDevice9_BeginScene(device);
23034 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
23035 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
23036 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
23037 hr = IDirect3DDevice9_EndScene(device);
23038 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
23040 /* Index 256 is out of bounds for selected shader in HW mode. c[256] is 0 most of the time. It
23041 is not guaranteed across all the adapters though, so disabling test. */
23042 #if 0
23043 expected_color = 0x000000ff;
23044 color = getPixelColor(device, 5, 5);
23045 ok(color == expected_color, "Expected color 0x%08x, got 0x%08x (shader in hw mode).\n",
23046 expected_color, color);
23047 #endif
23049 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
23050 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
23051 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
23052 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
23054 hr = IDirect3DDevice9_BeginScene(device);
23055 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
23056 hr = IDirect3DDevice9_SetSoftwareVertexProcessing(device, 1);
23057 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
23058 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
23059 hr = IDirect3DDevice9_EndScene(device);
23060 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
23062 expected_color = 0x0000ffff; /* c[256] is c_color for SW shader. */
23063 color = getPixelColor(device, 5, 5);
23064 todo_wine
23065 ok(color == expected_color, "Expected color 0x%08x, got 0x%08x (shader in sw mode).\n",
23066 expected_color, color);
23068 IDirect3DVertexDeclaration9_Release(vertex_declaration);
23069 IDirect3DVertexShader9_Release(reladdr_shader);
23070 if (pure_sw_shader)
23071 IDirect3DVertexShader9_Release(pure_sw_shader);
23072 refcount = IDirect3DDevice9_Release(device);
23073 ok(!refcount, "Device has %u references left.\n", refcount);
23074 done:
23075 IDirect3D9_Release(d3d);
23076 DestroyWindow(window);
23079 static void test_null_format(void)
23081 static const D3DVIEWPORT9 vp_lower = {0, 60, 640, 420, 0.0f, 1.0f};
23082 static const D3DVIEWPORT9 vp_560 = {0, 180, 560, 300, 0.0f, 1.0f};
23083 static const D3DVIEWPORT9 vp_full = {0, 0, 640, 480, 0.0f, 1.0f};
23084 static const DWORD null_fourcc = MAKEFOURCC('N','U','L','L');
23085 static const struct
23087 struct vec3 pos;
23088 DWORD diffuse;
23090 quad_partial[] =
23092 {{-1.0f, 0.5f, 0.1f}, 0x000000ff},
23093 {{ 0.5f, 0.5f, 0.1f}, 0x000000ff},
23094 {{-1.0f, -1.0f, 0.1f}, 0x000000ff},
23095 {{ 0.5f, -1.0f, 0.1f}, 0x000000ff},
23097 quad[] =
23099 {{-1.0f, 1.0f, 0.5f}, 0x00ff0000},
23100 {{ 1.0f, 1.0f, 0.5f}, 0x00ff0000},
23101 {{-1.0f, -1.0f, 0.5f}, 0x00ff0000},
23102 {{ 1.0f, -1.0f, 0.5f}, 0x00ff0000},
23104 quad_far[] =
23106 {{-1.0f, 1.0f, 1.0f}, 0x0000ff00},
23107 {{ 1.0f, 1.0f, 1.0f}, 0x0000ff00},
23108 {{-1.0f, -1.0f, 1.0f}, 0x0000ff00},
23109 {{ 1.0f, -1.0f, 1.0f}, 0x0000ff00},
23111 static const struct
23113 unsigned int x, y;
23114 D3DCOLOR color;
23115 BOOL todo;
23117 expected_colors[] =
23119 {200, 30, 0x0000ff00, FALSE},
23120 {440, 30, 0x0000ff00, FALSE},
23121 {520, 30, 0x0000ff00, FALSE},
23122 {600, 30, 0x0000ff00, FALSE},
23123 {200, 90, 0x00000000, FALSE},
23124 {440, 90, 0x0000ff00, FALSE},
23125 {520, 90, 0x0000ff00, FALSE},
23126 {600, 90, 0x0000ff00, FALSE},
23127 {200, 150, 0x000000ff, FALSE},
23128 {440, 150, 0x000000ff, FALSE},
23129 {520, 150, 0x0000ff00, FALSE},
23130 {600, 150, 0x0000ff00, FALSE},
23131 {200, 320, 0x000000ff, FALSE},
23132 {440, 320, 0x000000ff, FALSE},
23133 {520, 320, 0x00000000, TRUE},
23134 {600, 320, 0x0000ff00, FALSE},
23136 IDirect3DSurface9 *original_rt, *small_rt, *null_rt, *small_null_rt;
23137 IDirect3DDevice9 *device;
23138 IDirect3D9 *d3d;
23139 unsigned int i;
23140 D3DCOLOR color;
23141 HWND window;
23142 HRESULT hr;
23144 d3d = Direct3DCreate9(D3D_SDK_VERSION);
23145 ok(!!d3d, "Failed to create a D3D object.\n");
23147 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
23148 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, null_fourcc)))
23150 skip("No NULL format support, skipping NULL test.\n");
23151 IDirect3D9_Release(d3d);
23152 return;
23155 window = create_window();
23156 if (!(device = create_device(d3d, window, window, TRUE)))
23158 skip("Failed to create a D3D device.\n");
23159 IDirect3D9_Release(d3d);
23160 DestroyWindow(window);
23161 return;
23164 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
23165 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
23167 hr = IDirect3DDevice9_CreateRenderTarget(device, 400, 300, D3DFMT_A8R8G8B8,
23168 D3DMULTISAMPLE_NONE, 0, FALSE, &small_rt, NULL);
23169 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
23170 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, null_fourcc,
23171 D3DMULTISAMPLE_NONE, 0, FALSE, &null_rt, NULL);
23172 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
23173 hr = IDirect3DDevice9_CreateRenderTarget(device, 400, 300, null_fourcc,
23174 D3DMULTISAMPLE_NONE, 0, FALSE, &small_null_rt, NULL);
23175 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
23177 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
23178 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
23179 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
23180 ok(SUCCEEDED(hr), "Failed to enable depth test, hr %#x.\n", hr);
23181 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
23182 ok(SUCCEEDED(hr), "Failed to set depth function, hr %#x.\n", hr);
23183 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
23184 ok(SUCCEEDED(hr), "Failed to enable depth write, hr %#x.\n", hr);
23185 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
23186 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
23188 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
23189 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
23191 /* Clear extends to viewport size > RT size even if format is not
23192 * "NULL". */
23193 hr = IDirect3DDevice9_SetRenderTarget(device, 0, small_rt);
23194 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
23196 hr = IDirect3DDevice9_SetViewport(device, &vp_full);
23197 ok(hr == D3D_OK, "Failed to set viewport, hr %#x.\n", hr);
23199 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.2f, 0);
23200 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
23202 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
23203 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
23205 hr = IDirect3DDevice9_BeginScene(device);
23206 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
23207 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
23208 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
23209 hr = IDirect3DDevice9_EndScene(device);
23210 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
23212 hr = IDirect3DDevice9_SetRenderTarget(device, 0, null_rt);
23213 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
23214 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
23215 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
23217 /* Draw only extends to viewport size > RT size if format is "NULL". */
23218 hr = IDirect3DDevice9_SetRenderTarget(device, 0, small_rt);
23219 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
23220 hr = IDirect3DDevice9_SetViewport(device, &vp_lower);
23221 ok(hr == D3D_OK, "Failed to set viewport, hr %#x.\n", hr);
23222 hr = IDirect3DDevice9_BeginScene(device);
23223 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
23224 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
23225 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
23226 hr = IDirect3DDevice9_EndScene(device);
23227 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
23229 hr = IDirect3DDevice9_SetRenderTarget(device, 0, small_null_rt);
23230 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
23231 hr = IDirect3DDevice9_SetViewport(device, &vp_560);
23232 ok(hr == D3D_OK, "Failed to set viewport, hr %#x.\n", hr);
23233 hr = IDirect3DDevice9_BeginScene(device);
23234 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
23235 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
23236 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
23237 hr = IDirect3DDevice9_EndScene(device);
23238 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
23240 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
23241 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
23243 hr = IDirect3DDevice9_BeginScene(device);
23244 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
23245 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_partial, sizeof(*quad_partial));
23246 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
23247 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_far, sizeof(*quad_far));
23248 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
23249 hr = IDirect3DDevice9_EndScene(device);
23250 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
23252 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
23254 color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
23255 todo_wine_if(expected_colors[i].todo) ok(color_match(color, expected_colors[i].color, 1),
23256 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
23257 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
23260 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
23261 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
23263 IDirect3DSurface9_Release(small_null_rt);
23264 IDirect3DSurface9_Release(null_rt);
23265 IDirect3DSurface9_Release(small_rt);
23266 IDirect3DSurface9_Release(original_rt);
23267 cleanup_device(device);
23268 IDirect3D9_Release(d3d);
23271 static void test_map_synchronisation(void)
23273 LARGE_INTEGER frequency, diff, ts[3];
23274 unsigned int i, j, tri_count, size;
23275 D3DADAPTER_IDENTIFIER9 identifier;
23276 IDirect3DVertexBuffer9 *buffer;
23277 IDirect3DDevice9 *device;
23278 BOOL unsynchronised, ret;
23279 IDirect3D9 *d3d;
23280 D3DCOLOR colour;
23281 ULONG refcount;
23282 D3DCAPS9 caps;
23283 HWND window;
23284 HRESULT hr;
23286 static const struct
23288 unsigned int flags;
23289 BOOL unsynchronised;
23291 tests[] =
23293 {0, FALSE},
23294 {D3DLOCK_NOOVERWRITE, TRUE},
23295 {D3DLOCK_DISCARD, FALSE},
23296 {D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD, TRUE},
23299 static const struct quad
23301 struct
23303 struct vec3 position;
23304 DWORD diffuse;
23305 } strip[4];
23307 quad1 =
23310 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
23311 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
23312 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
23313 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
23316 quad2 =
23319 {{-1.0f, -1.0f, 0.0f}, 0xffffff00},
23320 {{-1.0f, 1.0f, 0.0f}, 0xffffff00},
23321 {{ 1.0f, -1.0f, 0.0f}, 0xffffff00},
23322 {{ 1.0f, 1.0f, 0.0f}, 0xffffff00},
23325 struct quad *quads;
23327 window = create_window();
23328 ok(!!window, "Failed to create a window.\n");
23330 d3d = Direct3DCreate9(D3D_SDK_VERSION);
23331 ok(!!d3d, "Failed to create a D3D object.\n");
23332 if (!(device = create_device(d3d, window, window, TRUE)))
23334 skip("Failed to create a D3D device, skipping tests.\n");
23335 IDirect3D9_Release(d3d);
23336 DestroyWindow(window);
23337 return;
23340 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
23341 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
23342 /* Maps are always synchronised on WARP. */
23343 if (adapter_is_warp(&identifier))
23345 skip("Running on WARP, skipping test.\n");
23346 goto done;
23349 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
23350 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
23352 tri_count = 0x1000;
23353 if (tri_count > caps.MaxPrimitiveCount)
23355 skip("Device supports only %u primitives, skipping test.\n", caps.MaxPrimitiveCount);
23356 goto done;
23358 size = (tri_count + 2) * sizeof(*quad1.strip);
23360 ret = QueryPerformanceFrequency(&frequency);
23361 ok(ret, "Failed to get performance counter frequency.\n");
23363 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
23364 D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &buffer, NULL);
23365 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
23366 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, size, (void **)&quads, D3DLOCK_DISCARD);
23367 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
23368 for (j = 0; j < size / sizeof(*quads); ++j)
23370 quads[j] = quad1;
23372 hr = IDirect3DVertexBuffer9_Unlock(buffer);
23373 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
23375 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
23376 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
23377 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
23378 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
23379 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(*quads->strip));
23380 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
23382 /* Initial draw to initialise states, compile shaders, etc. */
23383 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
23384 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
23385 hr = IDirect3DDevice9_BeginScene(device);
23386 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
23387 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, tri_count);
23388 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
23389 hr = IDirect3DDevice9_EndScene(device);
23390 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
23391 /* Read the result to ensure the GPU has finished drawing. */
23392 colour = getPixelColor(device, 320, 240);
23394 /* Time drawing tri_count triangles. */
23395 ret = QueryPerformanceCounter(&ts[0]);
23396 ok(ret, "Failed to read performance counter.\n");
23397 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
23398 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
23399 hr = IDirect3DDevice9_BeginScene(device);
23400 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
23401 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, tri_count);
23402 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
23403 hr = IDirect3DDevice9_EndScene(device);
23404 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
23405 colour = getPixelColor(device, 320, 240);
23406 /* Time drawing a single triangle. */
23407 ret = QueryPerformanceCounter(&ts[1]);
23408 ok(ret, "Failed to read performance counter.\n");
23409 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
23410 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
23411 hr = IDirect3DDevice9_BeginScene(device);
23412 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
23413 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 1);
23414 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
23415 hr = IDirect3DDevice9_EndScene(device);
23416 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
23417 colour = getPixelColor(device, 320, 240);
23418 ret = QueryPerformanceCounter(&ts[2]);
23419 ok(ret, "Failed to read performance counter.\n");
23421 IDirect3DVertexBuffer9_Release(buffer);
23423 /* Estimate the number of triangles we can draw in 100ms. */
23424 diff.QuadPart = ts[1].QuadPart - ts[0].QuadPart + ts[1].QuadPart - ts[2].QuadPart;
23425 tri_count = (tri_count * frequency.QuadPart) / (diff.QuadPart * 10);
23426 tri_count = ((tri_count + 2 + 3) & ~3) - 2;
23427 if (tri_count > caps.MaxPrimitiveCount)
23429 skip("Would need to draw %u triangles, but the device only supports %u primitives.\n",
23430 tri_count, caps.MaxPrimitiveCount);
23431 goto done;
23433 size = (tri_count + 2) * sizeof(*quad1.strip);
23435 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
23437 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
23438 D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &buffer, NULL);
23439 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
23440 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, size, (void **)&quads, D3DLOCK_DISCARD);
23441 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
23442 for (j = 0; j < size / sizeof(*quads); ++j)
23444 quads[j] = quad1;
23446 hr = IDirect3DVertexBuffer9_Unlock(buffer);
23447 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
23449 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(*quads->strip));
23450 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
23452 /* Start a draw operation. */
23453 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
23454 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
23455 hr = IDirect3DDevice9_BeginScene(device);
23456 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
23457 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, tri_count);
23458 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
23459 hr = IDirect3DDevice9_EndScene(device);
23460 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
23462 /* Map the last quad while the draw is in progress. */
23463 hr = IDirect3DVertexBuffer9_Lock(buffer, size - sizeof(quad2),
23464 sizeof(quad2), (void **)&quads, tests[i].flags);
23465 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
23466 *quads = quad2;
23467 hr = IDirect3DVertexBuffer9_Unlock(buffer);
23468 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
23470 colour = getPixelColor(device, 320, 240);
23471 unsynchronised = color_match(colour, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1);
23472 ok(tests[i].unsynchronised == unsynchronised, "Expected %s map for flags %#x.\n",
23473 tests[i].unsynchronised ? "unsynchronised" : "synchronised", tests[i].flags);
23475 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
23476 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
23478 IDirect3DVertexBuffer9_Release(buffer);
23481 done:
23482 refcount = IDirect3DDevice9_Release(device);
23483 ok(!refcount, "Device has %u references left.\n", refcount);
23484 IDirect3D9_Release(d3d);
23485 DestroyWindow(window);
23488 START_TEST(visual)
23490 D3DADAPTER_IDENTIFIER9 identifier;
23491 IDirect3D9 *d3d;
23492 HRESULT hr;
23494 if (!(d3d = Direct3DCreate9(D3D_SDK_VERSION)))
23496 skip("could not create D3D9 object\n");
23497 return;
23500 memset(&identifier, 0, sizeof(identifier));
23501 hr = IDirect3D9_GetAdapterIdentifier(d3d, 0, 0, &identifier);
23502 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
23503 trace("Driver string: \"%s\"\n", identifier.Driver);
23504 trace("Description string: \"%s\"\n", identifier.Description);
23505 /* Only Windows XP's default VGA driver should have an empty description */
23506 ok(identifier.Description[0] || broken(!strcmp(identifier.Driver, "vga.dll")), "Empty driver description.\n");
23507 trace("Device name string: \"%s\"\n", identifier.DeviceName);
23508 ok(identifier.DeviceName[0], "Empty device name.\n");
23509 trace("Driver version %d.%d.%d.%d\n",
23510 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
23511 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
23513 IDirect3D9_Release(d3d);
23515 test_sanity();
23516 depth_clamp_test();
23517 stretchrect_test();
23518 lighting_test();
23519 test_specular_lighting();
23520 clear_test();
23521 color_fill_test();
23522 fog_test();
23523 test_cube_wrap();
23524 z_range_test();
23525 maxmip_test();
23526 offscreen_test();
23527 ds_size_test();
23528 test_blend();
23529 test_shademode();
23530 srgbtexture_test();
23531 release_buffer_test();
23532 float_texture_test();
23533 g16r16_texture_test();
23534 pixelshader_blending_test();
23535 texture_transform_flags_test();
23536 test_mipmap_autogen();
23537 fixed_function_decl_test();
23538 conditional_np2_repeat_test();
23539 fixed_function_bumpmap_test();
23540 test_pointsize();
23541 tssargtemp_test();
23542 np2_stretch_rect_test();
23543 yuv_color_test();
23544 yuv_layout_test();
23545 zwriteenable_test();
23546 alphatest_test();
23547 viewport_test();
23548 test_constant_clamp_vs();
23549 test_compare_instructions();
23550 test_mova();
23551 loop_index_test();
23552 sincos_test();
23553 sgn_test();
23554 clip_planes_test();
23555 test_vshader_input();
23556 test_vshader_float16();
23557 stream_test();
23558 fog_with_shader_test();
23559 texbem_test();
23560 texdepth_test();
23561 texkill_test();
23562 volume_v16u16_test();
23563 constant_clamp_ps_test();
23564 cnd_test();
23565 dp2add_ps_test();
23566 unbound_sampler_test();
23567 nested_loop_test();
23568 pretransformed_varying_test();
23569 vface_register_test();
23570 test_fragment_coords();
23571 multiple_rendertargets_test();
23572 texop_test();
23573 texop_range_test();
23574 alphareplicate_test();
23575 dp3_alpha_test();
23576 depth_buffer_test();
23577 depth_buffer2_test();
23578 depth_blit_test();
23579 intz_test();
23580 shadow_test();
23581 fp_special_test();
23582 depth_bounds_test();
23583 srgbwrite_format_test();
23584 update_surface_test();
23585 multisample_get_rtdata_test();
23586 zenable_test();
23587 fog_special_test();
23588 volume_srgb_test();
23589 volume_dxt5_test();
23590 add_dirty_rect_test();
23591 multisampled_depth_buffer_test();
23592 resz_test();
23593 stencil_cull_test();
23594 test_per_stage_constant();
23595 test_3dc_formats();
23596 test_fog_interpolation();
23597 test_negative_fixedfunction_fog();
23598 test_position_index();
23599 test_table_fog_zw();
23600 test_signed_formats();
23601 test_multisample_mismatch();
23602 test_texcoordindex();
23603 test_vertex_blending();
23604 test_updatetexture();
23605 test_depthbias();
23606 test_flip();
23607 test_uninitialized_varyings();
23608 test_multisample_init();
23609 test_texture_blending();
23610 test_color_clamping();
23611 test_line_antialiasing_blending();
23612 test_dsy();
23613 test_evict_bound_resources();
23614 test_max_index16();
23615 test_backbuffer_resize();
23616 test_drawindexedprimitiveup();
23617 test_vertex_texture();
23618 test_mvp_software_vertex_shaders();
23619 test_null_format();
23620 test_map_synchronisation();