d3d9/tests: Add test for vertex textures.
[wine.git] / dlls / d3d9 / tests / visual.c
blob59a2e7de61329dfa89d7d57880770a761a521428
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 static const struct expected_color
640 unsigned int x, y;
641 D3DCOLOR color;
643 expected_directional[] =
645 {160, 120, 0x00ffffff},
646 {320, 120, 0x00ffffff},
647 {480, 120, 0x00ffffff},
648 {160, 240, 0x00ffffff},
649 {320, 240, 0x00ffffff},
650 {480, 240, 0x00ffffff},
651 {160, 360, 0x00ffffff},
652 {320, 360, 0x00ffffff},
653 {480, 360, 0x00ffffff},
655 expected_directional_local[] =
657 {160, 120, 0x003c3c3c},
658 {320, 120, 0x00717171},
659 {480, 120, 0x003c3c3c},
660 {160, 240, 0x00717171},
661 {320, 240, 0x00ffffff},
662 {480, 240, 0x00717171},
663 {160, 360, 0x003c3c3c},
664 {320, 360, 0x00717171},
665 {480, 360, 0x003c3c3c},
667 expected_point[] =
669 {160, 120, 0x00282828},
670 {320, 120, 0x005a5a5a},
671 {480, 120, 0x00282828},
672 {160, 240, 0x005a5a5a},
673 {320, 240, 0x00ffffff},
674 {480, 240, 0x005a5a5a},
675 {160, 360, 0x00282828},
676 {320, 360, 0x005a5a5a},
677 {480, 360, 0x00282828},
679 expected_point_local[] =
681 {160, 120, 0x00000000},
682 {320, 120, 0x00070707},
683 {480, 120, 0x00000000},
684 {160, 240, 0x00070707},
685 {320, 240, 0x00ffffff},
686 {480, 240, 0x00070707},
687 {160, 360, 0x00000000},
688 {320, 360, 0x00070707},
689 {480, 360, 0x00000000},
691 expected_spot[] =
693 {160, 120, 0x00000000},
694 {320, 120, 0x00141414},
695 {480, 120, 0x00000000},
696 {160, 240, 0x00141414},
697 {320, 240, 0x00ffffff},
698 {480, 240, 0x00141414},
699 {160, 360, 0x00000000},
700 {320, 360, 0x00141414},
701 {480, 360, 0x00000000},
703 expected_spot_local[] =
705 {160, 120, 0x00000000},
706 {320, 120, 0x00020202},
707 {480, 120, 0x00000000},
708 {160, 240, 0x00020202},
709 {320, 240, 0x00ffffff},
710 {480, 240, 0x00020202},
711 {160, 360, 0x00000000},
712 {320, 360, 0x00020202},
713 {480, 360, 0x00000000},
715 expected_point_range[] =
717 {160, 120, 0x00000000},
718 {320, 120, 0x005a5a5a},
719 {480, 120, 0x00000000},
720 {160, 240, 0x005a5a5a},
721 {320, 240, 0x00ffffff},
722 {480, 240, 0x005a5a5a},
723 {160, 360, 0x00000000},
724 {320, 360, 0x005a5a5a},
725 {480, 360, 0x00000000},
727 static const struct
729 const D3DLIGHT9 *light;
730 BOOL local_viewer;
731 const struct expected_color *expected;
732 unsigned int expected_count;
734 tests[] =
736 {&directional, FALSE, expected_directional,
737 sizeof(expected_directional) / sizeof(expected_directional[0])},
738 {&directional, TRUE, expected_directional_local,
739 sizeof(expected_directional_local) / sizeof(expected_directional_local[0])},
740 {&point, FALSE, expected_point,
741 sizeof(expected_point) / sizeof(expected_point[0])},
742 {&point, TRUE, expected_point_local,
743 sizeof(expected_point_local) / sizeof(expected_point_local[0])},
744 {&spot, FALSE, expected_spot,
745 sizeof(expected_spot) / sizeof(expected_spot[0])},
746 {&spot, TRUE, expected_spot_local,
747 sizeof(expected_spot_local) / sizeof(expected_spot_local[0])},
748 {&point_range, FALSE, expected_point_range,
749 sizeof(expected_point_range) / sizeof(expected_point_range[0])},
751 IDirect3DDevice9 *device;
752 D3DMATERIAL9 material;
753 IDirect3D9 *d3d;
754 D3DCOLOR color;
755 ULONG refcount;
756 HWND window;
757 HRESULT hr;
758 unsigned int i, j, x, y;
759 struct
761 struct vec3 position;
762 struct vec3 normal;
763 } *quad;
764 WORD *indices;
766 quad = HeapAlloc(GetProcessHeap(), 0, vertices_side * vertices_side * sizeof(*quad));
767 indices = HeapAlloc(GetProcessHeap(), 0, indices_count * sizeof(*indices));
768 for (i = 0, y = 0; y < vertices_side; ++y)
770 for (x = 0; x < vertices_side; ++x)
772 quad[i].position.x = x * 2.0f / (vertices_side - 1) - 1.0f;
773 quad[i].position.y = y * 2.0f / (vertices_side - 1) - 1.0f;
774 quad[i].position.z = 1.0f;
775 quad[i].normal.x = 0.0f;
776 quad[i].normal.y = 0.0f;
777 quad[i++].normal.z = -1.0f;
780 for (i = 0, y = 0; y < (vertices_side - 1); ++y)
782 for (x = 0; x < (vertices_side - 1); ++x)
784 indices[i++] = y * vertices_side + x + 1;
785 indices[i++] = y * vertices_side + x;
786 indices[i++] = (y + 1) * vertices_side + x;
787 indices[i++] = y * vertices_side + x + 1;
788 indices[i++] = (y + 1) * vertices_side + x;
789 indices[i++] = (y + 1) * vertices_side + x + 1;
793 window = create_window();
794 d3d = Direct3DCreate9(D3D_SDK_VERSION);
795 ok(!!d3d, "Failed to create a D3D object.\n");
796 if (!(device = create_device(d3d, window, window, TRUE)))
798 skip("Failed to create a D3D device, skipping tests.\n");
799 goto done;
802 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
803 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
804 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
805 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
806 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
807 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
808 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
809 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
810 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
811 ok(SUCCEEDED(hr), "Failed to disable z test, hr %#x.\n", hr);
812 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
813 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
815 hr = IDirect3DDevice9_SetFVF(device, fvf);
816 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
818 memset(&material, 0, sizeof(material));
819 material.Specular.r = 1.0f;
820 material.Specular.g = 1.0f;
821 material.Specular.b = 1.0f;
822 material.Specular.a = 1.0f;
823 material.Power = 30.0f;
824 hr = IDirect3DDevice9_SetMaterial(device, &material);
825 ok(SUCCEEDED(hr), "Failed to set material, hr %#x.\n", hr);
827 hr = IDirect3DDevice9_LightEnable(device, 0, TRUE);
828 ok(SUCCEEDED(hr), "Failed to enable light 0, hr %#x.\n", hr);
829 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
830 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#x.\n", hr);
832 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
834 hr = IDirect3DDevice9_SetLight(device, 0, tests[i].light);
835 ok(SUCCEEDED(hr), "Failed to set light parameters, hr %#x.\n", hr);
837 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LOCALVIEWER, tests[i].local_viewer);
838 ok(SUCCEEDED(hr), "Failed to set local viewer state, hr %#x.\n", hr);
840 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
841 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
843 hr = IDirect3DDevice9_BeginScene(device);
844 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
846 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST,
847 0, vertices_side * vertices_side, indices_count / 3, indices,
848 D3DFMT_INDEX16, quad, sizeof(quad[0]));
849 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
851 hr = IDirect3DDevice9_EndScene(device);
852 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
854 for (j = 0; j < tests[i].expected_count; ++j)
856 color = getPixelColor(device, tests[i].expected[j].x, tests[i].expected[j].y);
857 ok(color_match(color, tests[i].expected[j].color, 1),
858 "Expected color 0x%08x at location (%u, %u), got 0x%08x, case %u.\n",
859 tests[i].expected[j].color, tests[i].expected[j].x,
860 tests[i].expected[j].y, color, i);
864 refcount = IDirect3DDevice9_Release(device);
865 ok(!refcount, "Device has %u references left.\n", refcount);
866 done:
867 IDirect3D9_Release(d3d);
868 DestroyWindow(window);
869 HeapFree(GetProcessHeap(), 0, indices);
870 HeapFree(GetProcessHeap(), 0, quad);
873 static void clear_test(void)
875 static const D3DMATRIX mat =
877 1.0f, 0.0f, 0.0f, 0.0f,
878 0.0f, 1.0f, 0.0f, 0.0f,
879 0.0f, 0.0f, 1.0f, 0.0f,
880 0.0f, 0.0f, 0.0f, 1.0f,
881 }}};
882 static const struct
884 struct vec3 position;
885 DWORD diffuse;
887 quad[] =
889 {{-1.0f, -1.0f, 0.1f}, 0xff7f7f7f},
890 {{ 1.0f, -1.0f, 0.1f}, 0xff7f7f7f},
891 {{-1.0f, 1.0f, 0.1f}, 0xff7f7f7f},
892 {{ 1.0f, 1.0f, 0.1f}, 0xff7f7f7f},
894 IDirect3DSurface9 *surface0, *surface1, *backbuffer;
895 IDirect3DTexture9 *texture;
896 HRESULT hr;
897 D3DRECT rect[2];
898 D3DRECT rect_negneg;
899 DWORD color;
900 D3DVIEWPORT9 old_vp, vp;
901 RECT scissor;
902 DWORD oldColorWrite;
903 BOOL invalid_clear_failed = FALSE, srgb_supported;
904 IDirect3DDevice9 *device;
905 IDirect3D9 *d3d;
906 ULONG refcount;
907 HWND window;
909 window = create_window();
910 d3d = Direct3DCreate9(D3D_SDK_VERSION);
911 ok(!!d3d, "Failed to create a D3D object.\n");
912 if (!(device = create_device(d3d, window, window, TRUE)))
914 skip("Failed to create a D3D device, skipping tests.\n");
915 goto done;
918 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
919 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
921 /* Positive x, negative y */
922 rect[0].x1 = 0;
923 rect[0].y1 = 480;
924 rect[0].x2 = 320;
925 rect[0].y2 = 240;
927 /* Positive x, positive y */
928 rect[1].x1 = 0;
929 rect[1].y1 = 0;
930 rect[1].x2 = 320;
931 rect[1].y2 = 240;
932 /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
933 * returns D3D_OK, but ignores the rectangle silently
935 hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
936 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
937 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
939 /* negative x, negative y */
940 rect_negneg.x1 = 640;
941 rect_negneg.y1 = 240;
942 rect_negneg.x2 = 320;
943 rect_negneg.y2 = 0;
944 hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
945 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
946 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
948 color = getPixelColor(device, 160, 360); /* lower left quad */
949 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
950 color = getPixelColor(device, 160, 120); /* upper left quad */
951 if(invalid_clear_failed) {
952 /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
953 ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
954 } else {
955 /* If the negative rectangle was dropped silently, the correct ones are cleared */
956 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
958 color = getPixelColor(device, 480, 360); /* lower right quad */
959 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
960 color = getPixelColor(device, 480, 120); /* upper right quad */
961 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
963 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
965 /* Hack to work around a nvidia windows driver bug. The clear below is supposed to
966 * clear the red quad in the top left part of the render target. For some reason it
967 * doesn't work if the clear color is 0xffffffff on some versions of the Nvidia Windows
968 * driver(tested on 8.17.12.5896, Win7). A clear with a different color works around
969 * this bug and fixes the clear with the white color. Even 0xfeffffff works, but let's
970 * pick some obvious value
972 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbabe, 0.0, 0);
973 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
975 /* Test how the viewport affects clears */
976 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
977 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
978 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
979 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
981 vp.X = 160;
982 vp.Y = 120;
983 vp.Width = 160;
984 vp.Height = 120;
985 vp.MinZ = 0.0;
986 vp.MaxZ = 1.0;
987 hr = IDirect3DDevice9_SetViewport(device, &vp);
988 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
989 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
990 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
992 vp.X = 320;
993 vp.Y = 240;
994 vp.Width = 320;
995 vp.Height = 240;
996 vp.MinZ = 0.0;
997 vp.MaxZ = 1.0;
998 hr = IDirect3DDevice9_SetViewport(device, &vp);
999 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
1000 rect[0].x1 = 160;
1001 rect[0].y1 = 120;
1002 rect[0].x2 = 480;
1003 rect[0].y2 = 360;
1004 hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1005 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1007 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
1008 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
1010 color = getPixelColor(device, 158, 118);
1011 ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
1012 color = getPixelColor(device, 162, 118);
1013 ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
1014 color = getPixelColor(device, 158, 122);
1015 ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
1016 color = getPixelColor(device, 162, 122);
1017 ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
1019 color = getPixelColor(device, 318, 238);
1020 ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
1021 color = getPixelColor(device, 322, 238);
1022 ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
1023 color = getPixelColor(device, 318, 242);
1024 ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
1025 color = getPixelColor(device, 322, 242);
1026 ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
1028 color = getPixelColor(device, 478, 358);
1029 ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
1030 color = getPixelColor(device, 482, 358);
1031 ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
1032 color = getPixelColor(device, 478, 362);
1033 ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
1034 color = getPixelColor(device, 482, 362);
1035 ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
1037 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1039 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1040 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1042 SetRect(&scissor, 160, 120, 480, 360);
1043 hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
1044 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
1045 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
1046 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
1048 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1049 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1050 hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1051 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1053 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
1054 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
1056 color = getPixelColor(device, 158, 118);
1057 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
1058 color = getPixelColor(device, 162, 118);
1059 ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
1060 color = getPixelColor(device, 158, 122);
1061 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
1062 color = getPixelColor(device, 162, 122);
1063 ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
1065 color = getPixelColor(device, 158, 358);
1066 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
1067 color = getPixelColor(device, 162, 358);
1068 ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
1069 color = getPixelColor(device, 158, 358);
1070 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
1071 color = getPixelColor(device, 162, 362);
1072 ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
1074 color = getPixelColor(device, 478, 118);
1075 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
1076 color = getPixelColor(device, 478, 122);
1077 ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
1078 color = getPixelColor(device, 482, 122);
1079 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
1080 color = getPixelColor(device, 482, 358);
1081 ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
1083 color = getPixelColor(device, 478, 358);
1084 ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
1085 color = getPixelColor(device, 478, 362);
1086 ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
1087 color = getPixelColor(device, 482, 358);
1088 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
1089 color = getPixelColor(device, 482, 362);
1090 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
1092 color = getPixelColor(device, 318, 238);
1093 ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
1094 color = getPixelColor(device, 318, 242);
1095 ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
1096 color = getPixelColor(device, 322, 238);
1097 ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
1098 color = getPixelColor(device, 322, 242);
1099 ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
1101 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1103 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
1104 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1105 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
1106 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
1108 /* Same nvidia windows driver trouble with white clears as earlier in the same test */
1109 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbeef, 0.0, 0);
1110 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1112 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1113 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1115 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
1116 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
1118 /* Colorwriteenable does not affect the clear */
1119 color = getPixelColor(device, 320, 240);
1120 ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
1122 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1124 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
1125 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1127 rect[0].x1 = 0;
1128 rect[0].y1 = 0;
1129 rect[0].x2 = 640;
1130 rect[0].y2 = 480;
1131 hr = IDirect3DDevice9_Clear(device, 0, rect, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
1132 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1134 color = getPixelColor(device, 320, 240);
1135 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), 1),
1136 "Clear with count = 0, rect != NULL has color %08x\n", color);
1138 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1140 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1141 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1142 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1143 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1145 color = getPixelColor(device, 320, 240);
1146 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1147 "Clear with count = 1, rect = NULL has color %08x\n", color);
1149 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1151 /* Test D3DRS_SRGBWRITEENABLE interactions with clears. */
1152 srgb_supported = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
1153 D3DUSAGE_QUERY_SRGBWRITE, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8));
1154 trace("sRGB writing to D3DFMT_A8R8G8B8 is %ssupported.\n", srgb_supported ? "" : "not ");
1155 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1156 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
1158 color = getPixelColor(device, 320, 240);
1159 ok(color_match(color, 0x007f7f7f, 1), "Clear has color %08x.\n", color);
1161 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
1162 ok(SUCCEEDED(hr), "Failed to enable sRGB write, hr %#x.\n", hr);
1164 /* Draw something to make sure the SRGBWRITEENABLE setting is applied. */
1165 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
1166 ok(SUCCEEDED(hr), "Failed to set world matrix, hr %#x.\n", hr);
1167 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
1168 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
1169 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
1170 ok(SUCCEEDED(hr), "Failed to disable z test, hr %#x.\n", hr);
1171 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1172 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
1173 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
1174 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#x.\n", hr);
1175 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
1176 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
1177 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1178 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
1179 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1180 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1181 hr = IDirect3DDevice9_BeginScene(device);
1182 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1183 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad));
1184 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1185 hr = IDirect3DDevice9_EndScene(device);
1186 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1188 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1189 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
1191 color = getPixelColor(device, 320, 240);
1192 ok(color_match(color, 0x00bbbbbb, 1), "Clear has color %08x.\n", color);
1194 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
1195 ok(SUCCEEDED(hr), "Failed to disable sRGB write, hr %#x.\n", hr);
1197 /* Switching to a new render target seems to be enough to make Windows pick
1198 * up on the changed render state. */
1199 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 2, D3DUSAGE_RENDERTARGET,
1200 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
1201 ok(SUCCEEDED(hr), "Failed to create the offscreen render target, hr %#x.\n", hr);
1202 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1203 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
1204 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface0);
1205 ok(SUCCEEDED(hr), "Failed to get offscreen surface, hr %#x.\n", hr);
1206 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface0);
1207 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1209 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1210 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
1212 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1213 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1215 hr = IDirect3DDevice9_StretchRect(device, surface0, NULL, backbuffer, NULL, D3DTEXF_NONE);
1216 ok(SUCCEEDED(hr), "Failed to blit surface, hr %#x.\n", hr);
1218 color = getPixelColor(device, 64, 64);
1219 ok(color_match(color, 0x007f7f7f, 1), "Clear has color %08x.\n", color);
1221 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
1222 ok(SUCCEEDED(hr), "Failed to enable sRGB write, hr %#x.\n", hr);
1224 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface0);
1225 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1227 hr = IDirect3DDevice9_BeginScene(device);
1228 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1229 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad));
1230 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1231 hr = IDirect3DDevice9_EndScene(device);
1232 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1234 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1235 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
1237 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1238 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1240 hr = IDirect3DDevice9_StretchRect(device, surface0, NULL, backbuffer, NULL, D3DTEXF_NONE);
1241 ok(SUCCEEDED(hr), "Failed to blit surface, hr %#x.\n", hr);
1243 color = getPixelColor(device, 320, 240);
1244 ok(color_match(color, 0x00bbbbbb, 1), "Clear has color %08x.\n", color);
1246 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
1247 ok(SUCCEEDED(hr), "Failed to disable sRGB write, hr %#x.\n", hr);
1248 /* Switching to another surface of the same texture is also enough to make
1249 * the setting "stick". */
1250 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface1);
1251 ok(SUCCEEDED(hr), "Failed to get offscreen surface, hr %#x.\n", hr);
1252 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface1);
1253 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1255 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1256 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
1258 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1259 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1261 hr = IDirect3DDevice9_StretchRect(device, surface1, NULL, backbuffer, NULL, D3DTEXF_NONE);
1262 ok(SUCCEEDED(hr), "Failed to blit surface, hr %#x.\n", hr);
1264 color = getPixelColor(device, 320, 240);
1265 ok(color_match(color, 0x007f7f7f, 1), "Clear has color %08x.\n", color);
1267 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1269 IDirect3DSurface9_Release(surface1);
1270 IDirect3DSurface9_Release(surface0);
1271 IDirect3DSurface9_Release(backbuffer);
1272 IDirect3DTexture9_Release(texture);
1273 refcount = IDirect3DDevice9_Release(device);
1274 ok(!refcount, "Device has %u references left.\n", refcount);
1275 done:
1276 IDirect3D9_Release(d3d);
1277 DestroyWindow(window);
1280 static void color_fill_test(void)
1282 IDirect3DSurface9 *surface;
1283 IDirect3DTexture9 *texture;
1284 D3DCOLOR fill_color, color;
1285 DWORD fill_a, expected_a;
1286 IDirect3DDevice9 *device;
1287 IDirect3D9 *d3d;
1288 ULONG refcount;
1289 HWND window;
1290 HRESULT hr;
1291 static const struct
1293 D3DPOOL pool;
1294 DWORD usage;
1295 HRESULT hr;
1297 resource_types[] =
1299 {D3DPOOL_DEFAULT, 0, D3DERR_INVALIDCALL},
1300 {D3DPOOL_DEFAULT, D3DUSAGE_DYNAMIC, D3DERR_INVALIDCALL},
1301 {D3DPOOL_DEFAULT, D3DUSAGE_RENDERTARGET, D3D_OK},
1302 {D3DPOOL_SYSTEMMEM, 0, D3DERR_INVALIDCALL},
1303 {D3DPOOL_MANAGED, 0, D3DERR_INVALIDCALL},
1304 {D3DPOOL_SCRATCH, 0, D3DERR_INVALIDCALL},
1306 static const struct
1308 D3DFORMAT format;
1309 const char *name;
1310 enum
1312 CHECK_FILL_VALUE = 0x1,
1313 TODO_FILL_RETURN = 0x2,
1314 BLOCKS = 0x4,
1315 } flags;
1316 DWORD fill_value;
1318 formats[] =
1320 {D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8", CHECK_FILL_VALUE, 0xdeadbeef},
1321 /* D3DFMT_X8R8G8B8 either set X = A or X = 0, depending on the driver. */
1322 {D3DFMT_R5G6B5, "D3DFMT_R5G6B5", CHECK_FILL_VALUE, 0xadfdadfd},
1323 {D3DFMT_G16R16, "D3DFMT_G16R16", CHECK_FILL_VALUE, 0xbebeadad},
1324 /* Real hardware reliably fills the surface with the blue channel but
1325 * the testbot fills it with 0x00. Wine incorrectly uses the alpha
1326 * channel. Don't bother checking the result because P8 surfaces are
1327 * essentially useless in d3d9. */
1328 {D3DFMT_P8, "D3DFMT_P8", 0, 0xefefefef},
1329 /* Windows drivers produce different results for these formats.
1330 * No driver produces a YUV value that matches the input RGB
1331 * value, and no driver produces a proper DXT compression block.
1333 * Even the clear value 0 does not reliably produce a fill value
1334 * that will return vec4(0.0, 0.0, 0.0, 0.0) when sampled.
1336 * The YUV tests are disabled because they produce a driver-dependent
1337 * result on Wine.
1338 * {D3DFMT_YUY2, "D3DFMT_YUY2", BLOCKS, 0},
1339 * {D3DFMT_UYVY, "D3DFMT_UYVY", BLOCKS, 0}, */
1340 {D3DFMT_DXT1, "D3DFMT_DXT1", BLOCKS | TODO_FILL_RETURN, 0},
1341 /* Vendor-specific formats like ATI2N are a non-issue here since they're not
1342 * supported as offscreen plain surfaces and do not support D3DUSAGE_RENDERTARGET
1343 * when created as texture. */
1345 unsigned int i;
1346 D3DLOCKED_RECT locked_rect;
1347 DWORD *surface_data;
1348 static const RECT rect = {4, 4, 8, 8}, rect2 = {5, 5, 7, 7};
1350 window = create_window();
1351 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1352 ok(!!d3d, "Failed to create a D3D object.\n");
1353 if (!(device = create_device(d3d, window, window, TRUE)))
1355 skip("Failed to create a D3D device, skipping tests.\n");
1356 goto done;
1359 /* Test ColorFill on a the backbuffer (should pass) */
1360 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &surface);
1361 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1363 fill_color = 0x112233;
1364 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1365 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
1367 color = getPixelColor(device, 0, 0);
1368 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
1370 IDirect3DSurface9_Release(surface);
1372 /* Test ColorFill on a render target surface (should pass) */
1373 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8,
1374 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL );
1375 ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
1377 fill_color = 0x445566;
1378 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1379 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
1381 color = getPixelColorFromSurface(surface, 0, 0);
1382 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
1384 IDirect3DSurface9_Release(surface);
1386 /* Test ColorFill on an offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
1387 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1388 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surface, NULL);
1389 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
1391 fill_color = 0x778899;
1392 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1393 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
1395 color = getPixelColorFromSurface(surface, 0, 0);
1396 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
1398 IDirect3DSurface9_Release(surface);
1400 /* Try ColorFill on an offscreen surface in sysmem (should fail) */
1401 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1402 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1403 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
1405 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, 0);
1406 ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
1408 IDirect3DSurface9_Release(surface);
1410 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D16,
1411 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
1412 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr = %08x.\n", hr);
1414 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, 0);
1415 ok(hr == D3DERR_INVALIDCALL, "ColorFill on a depth stencil surface returned hr = %08x.\n", hr);
1417 IDirect3DSurface9_Release(surface);
1419 for (i = 0; i < sizeof(resource_types) / sizeof(resource_types[0]); i++)
1421 texture = NULL;
1422 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, resource_types[i].usage,
1423 D3DFMT_A8R8G8B8, resource_types[i].pool, &texture, NULL);
1424 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, i=%u.\n", hr, i);
1425 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1426 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x, i=%u.\n", hr, i);
1428 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1429 ok(hr == resource_types[i].hr, "Got unexpected hr %#x, expected %#x, i=%u.\n",
1430 hr, resource_types[i].hr, i);
1432 IDirect3DSurface9_Release(surface);
1433 IDirect3DTexture9_Release(texture);
1436 for (i = 0; i < sizeof(formats) / sizeof(formats[0]); i++)
1438 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
1439 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, formats[i].format) != D3D_OK)
1441 skip("Offscreenplain %s surfaces not supported, skipping colorfill test\n", formats[i].name);
1442 continue;
1445 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1446 formats[i].format, D3DPOOL_DEFAULT, &surface, NULL);
1447 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x, fmt=%s.\n", hr, formats[i].name);
1449 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, 0xdeadbeef);
1450 todo_wine_if (formats[i].flags & TODO_FILL_RETURN)
1451 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x, fmt=%s.\n", hr, formats[i].name);
1453 hr = IDirect3DDevice9_ColorFill(device, surface, &rect, 0xdeadbeef);
1454 todo_wine_if (formats[i].flags & TODO_FILL_RETURN)
1455 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x, fmt=%s.\n", hr, formats[i].name);
1457 if (SUCCEEDED(hr))
1459 hr = IDirect3DDevice9_ColorFill(device, surface, &rect2, 0xdeadbeef);
1460 if (formats[i].flags & BLOCKS)
1461 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, fmt=%s.\n", hr, formats[i].name);
1462 else
1463 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x, fmt=%s.\n", hr, formats[i].name);
1466 if (formats[i].flags & CHECK_FILL_VALUE)
1468 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, D3DLOCK_READONLY);
1469 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x, fmt=%s.\n", hr, formats[i].name);
1470 surface_data = locked_rect.pBits;
1471 fill_a = (surface_data[0] & 0xff000000) >> 24;
1472 expected_a = (formats[i].fill_value & 0xff000000) >> 24;
1473 /* Windows drivers disagree on how to promote the 8 bit per channel
1474 * input argument to 16 bit for D3DFMT_G16R16. */
1475 ok(color_match(surface_data[0], formats[i].fill_value, 2) &&
1476 abs((expected_a) - (fill_a)) < 3,
1477 "Expected clear value 0x%08x, got 0x%08x, fmt=%s.\n",
1478 formats[i].fill_value, surface_data[0], formats[i].name);
1479 hr = IDirect3DSurface9_UnlockRect(surface);
1480 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, fmt=%s.\n", hr, formats[i].name);
1483 IDirect3DSurface9_Release(surface);
1486 refcount = IDirect3DDevice9_Release(device);
1487 ok(!refcount, "Device has %u references left.\n", refcount);
1488 done:
1489 IDirect3D9_Release(d3d);
1490 DestroyWindow(window);
1494 * c7 mova ARGB mov ARGB
1495 * -2.4 -2 0x00ffff00 -3 0x00ff0000
1496 * -1.6 -2 0x00ffff00 -2 0x00ffff00
1497 * -0.4 0 0x0000ffff -1 0x0000ff00
1498 * 0.4 0 0x0000ffff 0 0x0000ffff
1499 * 1.6 2 0x00ff00ff 1 0x000000ff
1500 * 2.4 2 0x00ff00ff 2 0x00ff00ff
1502 static void test_mova(void)
1504 IDirect3DVertexDeclaration9 *vertex_declaration;
1505 IDirect3DVertexShader9 *mova_shader;
1506 IDirect3DVertexShader9 *mov_shader;
1507 IDirect3DDevice9 *device;
1508 unsigned int i, j;
1509 IDirect3D9 *d3d;
1510 ULONG refcount;
1511 D3DCAPS9 caps;
1512 HWND window;
1513 HRESULT hr;
1515 static const DWORD mova_test[] =
1517 0xfffe0200, /* vs_2_0 */
1518 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1519 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
1520 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
1521 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
1522 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
1523 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
1524 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
1525 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
1526 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
1527 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
1528 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1529 0x0000ffff /* END */
1531 static const DWORD mov_test[] =
1533 0xfffe0101, /* vs_1_1 */
1534 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1535 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
1536 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
1537 0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
1538 0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
1539 0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
1540 0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
1541 0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
1542 0x00000001, 0xb0010000, 0xa0000007, /* mov a0.x, c7.x */
1543 0x00000001, 0xd00f0000, 0xa0e42003, /* mov oD0, c[a0.x + 3] */
1544 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1545 0x0000ffff /* END */
1547 static const struct
1549 float in[4];
1550 DWORD out;
1552 test_data[2][6] =
1555 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
1556 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
1557 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
1558 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
1559 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
1560 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
1563 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
1564 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
1565 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
1566 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
1567 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
1568 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
1571 static const struct vec3 quad[] =
1573 {-1.0f, -1.0f, 0.0f},
1574 {-1.0f, 1.0f, 0.0f},
1575 { 1.0f, -1.0f, 0.0f},
1576 { 1.0f, 1.0f, 0.0f},
1578 static const D3DVERTEXELEMENT9 decl_elements[] =
1580 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1581 D3DDECL_END()
1584 window = create_window();
1585 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1586 ok(!!d3d, "Failed to create a D3D object.\n");
1587 if (!(device = create_device(d3d, window, window, TRUE)))
1589 skip("Failed to create a D3D device, skipping tests.\n");
1590 goto done;
1593 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1594 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1595 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
1597 skip("No vs_2_0 support, skipping tests.\n");
1598 IDirect3DDevice9_Release(device);
1599 goto done;
1602 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
1603 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1604 hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
1605 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1606 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1607 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1608 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1609 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1611 hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
1612 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1613 for (j = 0; j < sizeof(test_data) / sizeof(*test_data); ++j)
1615 for (i = 0; i < sizeof(*test_data) / sizeof(**test_data); ++i)
1617 DWORD color;
1619 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
1620 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
1622 hr = IDirect3DDevice9_BeginScene(device);
1623 ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
1625 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
1626 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1628 hr = IDirect3DDevice9_EndScene(device);
1629 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
1631 color = getPixelColor(device, 320, 240);
1632 ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
1633 test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
1635 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1636 ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
1638 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1639 ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
1641 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
1642 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1645 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1646 IDirect3DVertexShader9_Release(mova_shader);
1647 IDirect3DVertexShader9_Release(mov_shader);
1648 refcount = IDirect3DDevice9_Release(device);
1649 ok(!refcount, "Device has %u references left.\n", refcount);
1650 done:
1651 IDirect3D9_Release(d3d);
1652 DestroyWindow(window);
1655 static void fog_test(void)
1657 float start = 0.0f, end = 1.0f;
1658 IDirect3DDevice9 *device;
1659 IDirect3D9 *d3d;
1660 D3DCOLOR color;
1661 ULONG refcount;
1662 D3DCAPS9 caps;
1663 HWND window;
1664 HRESULT hr;
1665 int i;
1667 /* Gets full z based fog with linear fog, no fog with specular color. */
1668 static const struct
1670 float x, y, z;
1671 D3DCOLOR diffuse;
1672 D3DCOLOR specular;
1674 untransformed_1[] =
1676 {-1.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
1677 {-1.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
1678 { 0.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
1679 { 0.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
1681 /* Ok, I am too lazy to deal with transform matrices. */
1682 untransformed_2[] =
1684 {-1.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
1685 {-1.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
1686 { 0.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
1687 { 0.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
1689 untransformed_3[] =
1691 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1692 {-1.0f, 1.0f, 0.5f, 0xffff0000, 0xff000000},
1693 { 1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1694 { 1.0f, 1.0f, 0.5f, 0xffff0000, 0xff000000},
1696 far_quad1[] =
1698 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1699 {-1.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
1700 { 0.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
1701 { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1703 far_quad2[] =
1705 {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1706 {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
1707 { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
1708 { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1710 /* Untransformed ones. Give them a different diffuse color to make the
1711 * test look nicer. It also makes making sure that they are drawn
1712 * correctly easier. */
1713 static const struct
1715 float x, y, z, rhw;
1716 D3DCOLOR diffuse;
1717 D3DCOLOR specular;
1719 transformed_1[] =
1721 {320.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1722 {640.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1723 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1724 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1726 transformed_2[] =
1728 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1729 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1730 {640.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1731 {320.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1733 static const struct
1735 struct vec3 position;
1736 DWORD diffuse;
1738 rev_fog_quads[] =
1740 {{-1.0f, -1.0f, 0.1f}, 0x000000ff},
1741 {{-1.0f, 0.0f, 0.1f}, 0x000000ff},
1742 {{ 0.0f, 0.0f, 0.1f}, 0x000000ff},
1743 {{ 0.0f, -1.0f, 0.1f}, 0x000000ff},
1745 {{ 0.0f, -1.0f, 0.9f}, 0x000000ff},
1746 {{ 0.0f, 0.0f, 0.9f}, 0x000000ff},
1747 {{ 1.0f, 0.0f, 0.9f}, 0x000000ff},
1748 {{ 1.0f, -1.0f, 0.9f}, 0x000000ff},
1750 {{ 0.0f, 0.0f, 0.4f}, 0x000000ff},
1751 {{ 0.0f, 1.0f, 0.4f}, 0x000000ff},
1752 {{ 1.0f, 1.0f, 0.4f}, 0x000000ff},
1753 {{ 1.0f, 0.0f, 0.4f}, 0x000000ff},
1755 {{-1.0f, 0.0f, 0.7f}, 0x000000ff},
1756 {{-1.0f, 1.0f, 0.7f}, 0x000000ff},
1757 {{ 0.0f, 1.0f, 0.7f}, 0x000000ff},
1758 {{ 0.0f, 0.0f, 0.7f}, 0x000000ff},
1760 static const D3DMATRIX ident_mat =
1762 1.0f, 0.0f, 0.0f, 0.0f,
1763 0.0f, 1.0f, 0.0f, 0.0f,
1764 0.0f, 0.0f, 1.0f, 0.0f,
1765 0.0f, 0.0f, 0.0f, 1.0f
1766 }}};
1767 static const D3DMATRIX world_mat1 =
1769 1.0f, 0.0f, 0.0f, 0.0f,
1770 0.0f, 1.0f, 0.0f, 0.0f,
1771 0.0f, 0.0f, 1.0f, 0.0f,
1772 0.0f, 0.0f, -0.5f, 1.0f
1773 }}};
1774 static const D3DMATRIX world_mat2 =
1776 1.0f, 0.0f, 0.0f, 0.0f,
1777 0.0f, 1.0f, 0.0f, 0.0f,
1778 0.0f, 0.0f, 1.0f, 0.0f,
1779 0.0f, 0.0f, 1.0f, 1.0f
1780 }}};
1781 static const D3DMATRIX proj_mat =
1783 1.0f, 0.0f, 0.0f, 0.0f,
1784 0.0f, 1.0f, 0.0f, 0.0f,
1785 0.0f, 0.0f, 1.0f, 0.0f,
1786 0.0f, 0.0f, -1.0f, 1.0f
1787 }}};
1788 static const WORD Indices[] = {0, 1, 2, 2, 3, 0};
1789 static const WORD Indices2[] =
1791 0, 1, 2, 2, 3, 0,
1792 4, 5, 6, 6, 7, 4,
1793 8, 9, 10, 10, 11, 8,
1794 12, 13, 14, 14, 15, 12,
1797 window = create_window();
1798 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1799 ok(!!d3d, "Failed to create a D3D object.\n");
1800 if (!(device = create_device(d3d, window, window, TRUE)))
1802 skip("Failed to create a D3D device, skipping tests.\n");
1803 goto done;
1806 memset(&caps, 0, sizeof(caps));
1807 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1808 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
1809 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1810 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1812 /* Setup initial states: No lighting, fog on, fog color */
1813 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
1814 ok(SUCCEEDED(hr), "Failed to disable D3DRS_ZENABLE, hr %#x.\n", hr);
1815 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1816 ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
1817 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1818 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
1819 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xff00ff00 /* A nice green */);
1820 ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
1821 /* Some of the tests seem to depend on the projection matrix explicitly
1822 * being set to an identity matrix, even though that's the default.
1823 * (AMD Radeon HD 6310, Windows 7) */
1824 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
1825 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
1827 /* First test: Both table fog and vertex fog off */
1828 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1829 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
1830 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1831 ok(hr == D3D_OK, "Turning off vertex fog returned %08x\n", hr);
1833 /* Start = 0, end = 1. Should be default, but set them */
1834 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1835 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1836 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1837 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1839 hr = IDirect3DDevice9_BeginScene(device);
1840 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1842 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1843 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1845 /* Untransformed, vertex fog = NONE, table fog = NONE:
1846 * Read the fog weighting from the specular color. */
1847 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1848 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1849 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1851 /* That makes it use the Z value */
1852 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1853 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex mode, hr %#x.\n", hr);
1854 /* Untransformed, vertex fog != none (or table fog != none):
1855 * Use the Z value as input into the equation. */
1856 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1857 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1858 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1860 /* transformed verts */
1861 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1862 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1863 /* Transformed, vertex fog != NONE, pixel fog == NONE:
1864 * Use specular color alpha component. */
1865 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1866 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_1, sizeof(transformed_1[0]));
1867 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1869 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1870 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog table mode, hr %#x.\n", hr);
1871 /* Transformed, table fog != none, vertex anything:
1872 * Use Z value as input to the fog equation. */
1873 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1874 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_2, sizeof(transformed_2[0]));
1875 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1877 hr = IDirect3DDevice9_EndScene(device);
1878 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1880 color = getPixelColor(device, 160, 360);
1881 ok(color == 0x00ff0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1882 color = getPixelColor(device, 160, 120);
1883 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
1884 color = getPixelColor(device, 480, 120);
1885 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1886 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1888 color = getPixelColor(device, 480, 360);
1889 ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
1891 else
1893 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1894 * The settings above result in no fogging with vertex fog
1896 color = getPixelColor(device, 480, 120);
1897 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1898 trace("Info: Table fog not supported by this device\n");
1900 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1902 /* Now test the special case fogstart == fogend */
1903 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1904 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1906 hr = IDirect3DDevice9_BeginScene(device);
1907 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1909 start = 512;
1910 end = 512;
1911 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
1912 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#x.\n", hr);
1913 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
1914 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#x.\n", hr);
1916 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1917 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1918 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1919 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex mode, hr %#x.\n", hr);
1920 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1921 ok(SUCCEEDED(hr), "Failed to set D3DFOG_NONE fog table mode, hr %#x.\n", hr);
1923 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512.
1924 * Would result in a completely fog-free primitive because start > zcoord,
1925 * but because start == end, the primitive is fully covered by fog. The
1926 * same happens to the 2nd untransformed quad with z = 1.0. The third
1927 * transformed quad remains unfogged because the fogcoords are read from
1928 * the specular color and has fixed fogstart and fogend. */
1929 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1930 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1931 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1932 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1933 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1934 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1936 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1937 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1938 /* Transformed, vertex fog != NONE, pixel fog == NONE:
1939 * Use specular color alpha component. */
1940 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1941 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_1, sizeof(transformed_1[0]));
1942 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1944 hr = IDirect3DDevice9_EndScene(device);
1945 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1947 color = getPixelColor(device, 160, 360);
1948 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1949 color = getPixelColor(device, 160, 120);
1950 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1951 color = getPixelColor(device, 480, 120);
1952 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1953 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1955 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1956 * but without shaders it seems to work everywhere
1958 end = 0.2;
1959 start = 0.8;
1960 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1961 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1962 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1963 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1964 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1965 ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1967 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1968 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1969 * so skip this for now
1971 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1972 const char *mode = (i ? "table" : "vertex");
1973 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1974 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1975 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1976 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1977 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1978 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1979 hr = IDirect3DDevice9_BeginScene(device);
1980 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1981 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 16 /* NumVerts */,
1982 8 /* PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads, sizeof(rev_fog_quads[0]));
1983 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1984 hr = IDirect3DDevice9_EndScene(device);
1985 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1987 color = getPixelColor(device, 160, 360);
1988 ok(color_match(color, 0x0000ff00, 1),
1989 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1991 color = getPixelColor(device, 160, 120);
1992 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1993 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1995 color = getPixelColor(device, 480, 120);
1996 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1997 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1999 color = getPixelColor(device, 480, 360);
2000 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
2002 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2004 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
2005 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
2006 break;
2010 if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
2012 /* A simple fog + non-identity world matrix test */
2013 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat1);
2014 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %#08x\n", hr);
2016 start = 0.0;
2017 end = 1.0;
2018 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
2019 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
2020 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
2021 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
2022 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
2023 ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
2024 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
2025 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
2027 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2028 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %#08x\n", hr);
2030 hr = IDirect3DDevice9_BeginScene(device);
2031 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2033 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
2034 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
2036 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2037 2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
2038 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2039 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2040 2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
2041 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2043 hr = IDirect3DDevice9_EndScene(device);
2044 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2046 color = getPixelColor(device, 160, 360);
2047 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 4),
2048 "Unfogged quad has color %08x\n", color);
2049 color = getPixelColor(device, 160, 120);
2050 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2051 "Fogged out quad has color %08x\n", color);
2053 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2055 /* Test fog behavior with an orthogonal (but non-identity) projection matrix */
2056 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat2);
2057 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
2058 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &proj_mat);
2059 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
2061 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2062 ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
2064 hr = IDirect3DDevice9_BeginScene(device);
2065 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2067 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
2068 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
2070 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2071 2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
2072 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2073 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2074 2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
2075 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2077 hr = IDirect3DDevice9_EndScene(device);
2078 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2080 color = getPixelColor(device, 160, 360);
2081 ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
2082 color = getPixelColor(device, 160, 120);
2083 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2084 "Fogged out quad has color %08x\n", color);
2086 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2088 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &ident_mat);
2089 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
2090 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
2091 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
2093 else
2095 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
2098 /* Test RANGEFOG vs FOGTABLEMODE */
2099 if ((caps.RasterCaps & (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE)) ==
2100 (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE))
2102 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2103 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
2104 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
2105 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
2107 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, TRUE);
2108 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
2110 /* z=0.5, x = +/- 1.0, y = +/- 1.0. In case of z fog the fog coordinate is
2111 * 0.5. With range fog it is sqrt(x*x + y*y + z*z) = 1.5 for all vertices.
2112 * Note that the fog coordinate is interpolated linearly across the vertices,
2113 * so the different eye distance at the screen center should not matter. */
2114 start = 0.75f;
2115 end = 0.75001f;
2116 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
2117 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
2118 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
2119 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
2121 /* Table fog: Range fog is not used */
2122 hr = IDirect3DDevice9_BeginScene(device);
2123 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2125 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
2126 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog table mode, hr %#x.\n", hr);
2127 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
2128 untransformed_3, sizeof(*untransformed_3));
2129 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2131 hr = IDirect3DDevice9_EndScene(device);
2132 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2134 color = getPixelColor(device, 10, 10);
2135 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2136 color = getPixelColor(device, 630, 10);
2137 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2138 color = getPixelColor(device, 10, 470);
2139 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2140 color = getPixelColor(device, 630, 470);
2141 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2143 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2144 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
2146 /* Vertex fog: Rangefog is used */
2147 hr = IDirect3DDevice9_BeginScene(device);
2148 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2150 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
2151 ok(SUCCEEDED(hr), "Failed to set D3DFOG_NONE fog table mode, hr %#x.\n", hr);
2152 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
2153 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex mode, hr %#x.\n", hr);
2154 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
2155 untransformed_3, sizeof(*untransformed_3));
2156 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2158 hr = IDirect3DDevice9_EndScene(device);
2159 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2161 color = getPixelColor(device, 10, 10);
2162 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2163 "Rangefog with vertex fog returned color 0x%08x\n", color);
2164 color = getPixelColor(device, 630, 10);
2165 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2166 "Rangefog with vertex fog returned color 0x%08x\n", color);
2167 color = getPixelColor(device, 10, 470);
2168 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2169 "Rangefog with vertex fog returned color 0x%08x\n", color);
2170 color = getPixelColor(device, 630, 470);
2171 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2172 "Rangefog with vertex fog returned color 0x%08x\n", color);
2174 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2175 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
2177 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, FALSE);
2178 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
2180 else
2182 skip("Range fog or table fog not supported, skipping range fog tests\n");
2185 refcount = IDirect3DDevice9_Release(device);
2186 ok(!refcount, "Device has %u references left.\n", refcount);
2187 done:
2188 IDirect3D9_Release(d3d);
2189 DestroyWindow(window);
2192 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
2193 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
2194 * regardless of the actual addressing mode set. The way this test works is
2195 * that we sample in one of the corners of the cubemap with filtering enabled,
2196 * and check the interpolated color. There are essentially two reasonable
2197 * things an implementation can do: Either pick one of the faces and
2198 * interpolate the edge texel with itself (i.e., clamp within the face), or
2199 * interpolate between the edge texels of the three involved faces. It should
2200 * never involve the border color or the other side (texcoord wrapping) of a
2201 * face in the interpolation. */
2202 static void test_cube_wrap(void)
2204 IDirect3DVertexDeclaration9 *vertex_declaration;
2205 IDirect3DSurface9 *face_surface, *surface;
2206 IDirect3DCubeTexture9 *texture;
2207 D3DLOCKED_RECT locked_rect;
2208 IDirect3DDevice9 *device;
2209 unsigned int x, y, face;
2210 IDirect3D9 *d3d;
2211 ULONG refcount;
2212 D3DCAPS9 caps;
2213 HWND window;
2214 HRESULT hr;
2216 static const float quad[][6] =
2218 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2219 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2220 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2221 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2223 static const D3DVERTEXELEMENT9 decl_elements[] =
2225 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2226 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2227 D3DDECL_END()
2229 static const struct
2231 D3DTEXTUREADDRESS mode;
2232 const char *name;
2234 address_modes[] =
2236 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
2237 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
2238 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
2239 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
2240 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
2243 window = create_window();
2244 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2245 ok(!!d3d, "Failed to create a D3D object.\n");
2246 if (!(device = create_device(d3d, window, window, TRUE)))
2248 skip("Failed to create a D3D device, skipping tests.\n");
2249 goto done;
2252 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2253 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2254 if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP))
2256 skip("No cube texture support, skipping tests.\n");
2257 IDirect3DDevice9_Release(device);
2258 goto done;
2261 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
2262 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
2263 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2264 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
2266 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
2267 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
2268 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
2270 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
2271 D3DPOOL_DEFAULT, &texture, NULL);
2272 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
2274 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
2275 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2277 for (y = 0; y < 128; ++y)
2279 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2280 for (x = 0; x < 64; ++x)
2282 *ptr++ = 0xff0000ff;
2284 for (x = 64; x < 128; ++x)
2286 *ptr++ = 0xffff0000;
2290 hr = IDirect3DSurface9_UnlockRect(surface);
2291 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2293 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
2294 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
2296 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
2297 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
2299 IDirect3DSurface9_Release(face_surface);
2301 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
2302 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2304 for (y = 0; y < 128; ++y)
2306 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2307 for (x = 0; x < 64; ++x)
2309 *ptr++ = 0xffff0000;
2311 for (x = 64; x < 128; ++x)
2313 *ptr++ = 0xff0000ff;
2317 hr = IDirect3DSurface9_UnlockRect(surface);
2318 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2320 /* Create cube faces */
2321 for (face = 1; face < 6; ++face)
2323 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
2324 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
2326 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
2327 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
2329 IDirect3DSurface9_Release(face_surface);
2332 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
2333 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2335 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
2336 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2337 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
2338 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2339 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
2340 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
2342 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2343 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2345 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
2347 DWORD color;
2349 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
2350 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
2351 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
2352 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
2354 hr = IDirect3DDevice9_BeginScene(device);
2355 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2357 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2358 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2360 hr = IDirect3DDevice9_EndScene(device);
2361 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2363 color = getPixelColor(device, 320, 240);
2364 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
2365 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
2366 color, address_modes[x].name);
2368 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2369 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2371 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
2372 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
2375 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2376 IDirect3DCubeTexture9_Release(texture);
2377 IDirect3DSurface9_Release(surface);
2378 refcount = IDirect3DDevice9_Release(device);
2379 ok(!refcount, "Device has %u references left.\n", refcount);
2380 done:
2381 IDirect3D9_Release(d3d);
2382 DestroyWindow(window);
2385 static void offscreen_test(void)
2387 IDirect3DSurface9 *backbuffer, *offscreen;
2388 IDirect3DTexture9 *offscreenTexture;
2389 IDirect3DDevice9 *device;
2390 IDirect3D9 *d3d;
2391 D3DCOLOR color;
2392 ULONG refcount;
2393 HWND window;
2394 HRESULT hr;
2396 static const float quad[][5] =
2398 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
2399 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
2400 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
2401 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
2404 window = create_window();
2405 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2406 ok(!!d3d, "Failed to create a D3D object.\n");
2407 if (!(device = create_device(d3d, window, window, TRUE)))
2409 skip("Failed to create a D3D device, skipping tests.\n");
2410 goto done;
2413 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
2414 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
2416 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2417 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
2418 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
2419 if (!offscreenTexture)
2421 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5.\n");
2422 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2423 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
2424 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
2425 if (!offscreenTexture)
2427 skip("Cannot create an offscreen render target.\n");
2428 IDirect3DDevice9_Release(device);
2429 goto done;
2433 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2434 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2436 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
2437 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
2439 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2440 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
2442 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
2443 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
2444 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2445 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
2446 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2447 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2448 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2449 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2450 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2451 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2453 hr = IDirect3DDevice9_BeginScene(device);
2454 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2456 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
2457 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2458 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 1.0f, 0);
2459 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2461 /* Draw without textures - Should result in a white quad. */
2462 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2463 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2465 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
2466 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2467 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)offscreenTexture);
2468 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2470 /* This time with the texture. */
2471 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2472 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2474 hr = IDirect3DDevice9_EndScene(device);
2475 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2477 /* Center quad - should be white */
2478 color = getPixelColor(device, 320, 240);
2479 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2480 /* Some quad in the cleared part of the texture */
2481 color = getPixelColor(device, 170, 240);
2482 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
2483 /* Part of the originally cleared back buffer */
2484 color = getPixelColor(device, 10, 10);
2485 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2486 color = getPixelColor(device, 10, 470);
2487 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2489 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2491 IDirect3DSurface9_Release(backbuffer);
2492 IDirect3DTexture9_Release(offscreenTexture);
2493 IDirect3DSurface9_Release(offscreen);
2494 refcount = IDirect3DDevice9_Release(device);
2495 ok(!refcount, "Device has %u references left.\n", refcount);
2496 done:
2497 IDirect3D9_Release(d3d);
2498 DestroyWindow(window);
2501 /* This test tests fog in combination with shaders.
2502 * What's tested: linear fog (vertex and table) with pixel shader
2503 * linear table fog with non foggy vertex shader
2504 * vertex fog with foggy vertex shader, non-linear
2505 * fog with shader, non-linear fog with foggy shader,
2506 * linear table fog with foggy shader */
2507 static void fog_with_shader_test(void)
2509 IDirect3DVertexShader9 *vertex_shader[4] = {NULL, NULL, NULL, NULL};
2510 IDirect3DPixelShader9 *pixel_shader[3] = {NULL, NULL, NULL};
2511 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
2512 IDirect3DDevice9 *device;
2513 unsigned int i, j;
2514 IDirect3D9 *d3d;
2515 ULONG refcount;
2516 D3DCAPS9 caps;
2517 DWORD color;
2518 HWND window;
2519 HRESULT hr;
2520 union
2522 float f;
2523 DWORD i;
2524 } start, end;
2526 /* basic vertex shader without fog computation ("non foggy") */
2527 static const DWORD vertex_shader_code1[] =
2529 0xfffe0101, /* vs_1_1 */
2530 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2531 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
2532 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2533 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
2534 0x0000ffff
2536 /* basic vertex shader with reversed fog computation ("foggy") */
2537 static const DWORD vertex_shader_code2[] =
2539 0xfffe0101, /* vs_1_1 */
2540 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2541 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
2542 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
2543 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2544 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
2545 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
2546 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
2547 0x0000ffff
2549 /* basic vertex shader with reversed fog computation ("foggy"), vs_2_0 */
2550 static const DWORD vertex_shader_code3[] =
2552 0xfffe0200, /* vs_2_0 */
2553 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2554 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
2555 0x05000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
2556 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2557 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
2558 0x03000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
2559 0x03000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
2560 0x0000ffff
2562 /* basic pixel shader */
2563 static const DWORD pixel_shader_code[] =
2565 0xffff0101, /* ps_1_1 */
2566 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
2567 0x0000ffff
2569 static const DWORD pixel_shader_code2[] =
2571 0xffff0200, /* ps_2_0 */
2572 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
2573 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
2574 0x0000ffff
2576 struct
2578 struct vec3 position;
2579 DWORD diffuse;
2581 quad[] =
2583 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
2584 {{-1.0f, 1.0f, 0.0f}, 0xffff0000},
2585 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
2586 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000},
2588 static const D3DVERTEXELEMENT9 decl_elements[] =
2590 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2591 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
2592 D3DDECL_END()
2594 /* This reference data was collected on a nVidia GeForce 7600GS driver
2595 * version 84.19 DirectX version 9.0c on Windows XP. */
2596 static const struct test_data_t
2598 int vshader;
2599 int pshader;
2600 D3DFOGMODE vfog;
2601 D3DFOGMODE tfog;
2602 unsigned int color[11];
2604 test_data[] =
2606 /* only pixel shader: */
2607 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
2608 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2609 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2610 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
2611 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2612 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2613 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
2614 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2615 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2616 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2617 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2618 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2619 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
2620 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2621 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2623 /* vertex shader */
2624 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
2625 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2626 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2627 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
2628 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2629 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2630 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
2631 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2632 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2634 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
2635 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2636 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2637 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
2638 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2639 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2641 /* vertex shader and pixel shader */
2642 /* The next 4 tests would read the fog coord output, but it isn't available.
2643 * The result is a fully fogged quad, no matter what the Z coord is. This is on
2644 * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
2645 * These tests should be disabled if some other hardware behaves differently
2647 {1, 1, D3DFOG_NONE, D3DFOG_NONE,
2648 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2649 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2650 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2651 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2652 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2653 {1, 1, D3DFOG_EXP, D3DFOG_NONE,
2654 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2655 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2656 {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
2657 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2658 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2660 /* These use the Z coordinate with linear table fog */
2661 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
2662 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2663 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2664 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
2665 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2666 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2667 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
2668 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2669 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2670 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
2671 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2672 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2674 /* Non-linear table fog without fog coord */
2675 {1, 1, D3DFOG_NONE, D3DFOG_EXP,
2676 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
2677 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
2678 {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
2679 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
2680 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
2682 /* These tests fail on older Nvidia drivers */
2683 /* foggy vertex shader */
2684 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
2685 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2686 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2687 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
2688 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2689 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2690 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
2691 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2692 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2693 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
2694 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2695 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2697 {3, 0, D3DFOG_NONE, D3DFOG_NONE,
2698 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2699 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2700 {3, 0, D3DFOG_EXP, D3DFOG_NONE,
2701 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2702 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2703 {3, 0, D3DFOG_EXP2, D3DFOG_NONE,
2704 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2705 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2706 {3, 0, D3DFOG_LINEAR, D3DFOG_NONE,
2707 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2708 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2710 /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
2711 * all using the fixed fog-coord linear fog
2713 /* vs_1_1 with ps_1_1 */
2714 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
2715 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2716 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2717 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
2718 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2719 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2720 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
2721 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2722 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2723 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2724 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2725 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2727 /* vs_2_0 with ps_1_1 */
2728 {3, 1, D3DFOG_NONE, D3DFOG_NONE,
2729 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2730 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2731 {3, 1, D3DFOG_EXP, D3DFOG_NONE,
2732 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2733 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2734 {3, 1, D3DFOG_EXP2, D3DFOG_NONE,
2735 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2736 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2737 {3, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2738 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2739 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2741 /* vs_1_1 with ps_2_0 */
2742 {2, 2, D3DFOG_NONE, D3DFOG_NONE,
2743 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2744 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2745 {2, 2, D3DFOG_EXP, D3DFOG_NONE,
2746 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2747 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2748 {2, 2, D3DFOG_EXP2, D3DFOG_NONE,
2749 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2750 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2751 {2, 2, D3DFOG_LINEAR, D3DFOG_NONE,
2752 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2753 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2755 /* vs_2_0 with ps_2_0 */
2756 {3, 2, D3DFOG_NONE, D3DFOG_NONE,
2757 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2758 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2759 {3, 2, D3DFOG_EXP, D3DFOG_NONE,
2760 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2761 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2762 {3, 2, D3DFOG_EXP2, D3DFOG_NONE,
2763 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2764 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2765 {3, 2, D3DFOG_LINEAR, D3DFOG_NONE,
2766 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2767 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2769 /* These use table fog. Here the shader-provided fog coordinate is
2770 * ignored and the z coordinate used instead
2772 {2, 1, D3DFOG_NONE, D3DFOG_EXP,
2773 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
2774 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
2775 {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
2776 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
2777 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
2778 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
2779 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2780 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2782 static const D3DMATRIX identity =
2784 1.0f, 0.0f, 0.0f, 0.0f,
2785 0.0f, 1.0f, 0.0f, 0.0f,
2786 0.0f, 0.0f, 1.0f, 0.0f,
2787 0.0f, 0.0f, 0.0f, 1.0f,
2788 }}};
2790 window = create_window();
2791 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2792 ok(!!d3d, "Failed to create a D3D object.\n");
2793 if (!(device = create_device(d3d, window, window, TRUE)))
2795 skip("Failed to create a D3D device, skipping tests.\n");
2796 goto done;
2799 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2800 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2801 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0) || caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
2803 skip("No shader model 2 support, skipping tests.\n");
2804 IDirect3DDevice9_Release(device);
2805 goto done;
2808 /* NOTE: Changing these values will not affect the tests with foggy vertex
2809 * shader, as the values are hardcoded in the shader. */
2810 start.f = 0.1f;
2811 end.f = 0.9f;
2813 /* Some of the tests seem to depend on the projection matrix explicitly
2814 * being set to an identity matrix, even though that's the default.
2815 * (AMD Radeon HD 6310, Windows 7) */
2816 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
2817 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
2819 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
2820 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2821 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
2822 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2823 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code3, &vertex_shader[3]);
2824 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2825 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
2826 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2827 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code2, &pixel_shader[2]);
2828 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2829 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
2830 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
2832 /* Setup initial states: No lighting, fog on, fog color */
2833 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2834 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
2835 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
2836 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
2837 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xff00ff00 /* A nice green */);
2838 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
2839 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2840 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2842 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
2843 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
2844 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
2845 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
2847 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
2848 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
2849 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
2850 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
2851 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
2853 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
2855 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
2856 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2857 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
2858 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2859 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
2860 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2861 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
2862 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2864 for(j=0; j < 11; j++)
2866 /* Don't use the whole zrange to prevent rounding errors */
2867 quad[0].position.z = 0.001f + (float)j / 10.02f;
2868 quad[1].position.z = 0.001f + (float)j / 10.02f;
2869 quad[2].position.z = 0.001f + (float)j / 10.02f;
2870 quad[3].position.z = 0.001f + (float)j / 10.02f;
2872 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff00ff, 1.0f, 0);
2873 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2875 hr = IDirect3DDevice9_BeginScene(device);
2876 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
2878 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2879 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2881 hr = IDirect3DDevice9_EndScene(device);
2882 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
2884 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
2885 color = getPixelColor(device, 128, 240);
2886 ok(color_match(color, test_data[i].color[j], 13),
2887 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
2888 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
2891 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2893 IDirect3DVertexShader9_Release(vertex_shader[1]);
2894 IDirect3DVertexShader9_Release(vertex_shader[2]);
2895 IDirect3DVertexShader9_Release(vertex_shader[3]);
2896 IDirect3DPixelShader9_Release(pixel_shader[1]);
2897 IDirect3DPixelShader9_Release(pixel_shader[2]);
2898 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2899 refcount = IDirect3DDevice9_Release(device);
2900 ok(!refcount, "Device has %u references left.\n", refcount);
2901 done:
2902 IDirect3D9_Release(d3d);
2903 DestroyWindow(window);
2906 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
2907 unsigned int i, x, y;
2908 HRESULT hr;
2909 IDirect3DTexture9 *texture[2] = {NULL, NULL};
2910 D3DLOCKED_RECT locked_rect;
2912 /* Generate the textures */
2913 for(i=0; i<2; i++)
2915 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
2916 D3DPOOL_MANAGED, &texture[i], NULL);
2917 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
2919 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
2920 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2921 for (y = 0; y < 128; ++y)
2923 if(i)
2924 { /* Set up black texture with 2x2 texel white spot in the middle */
2925 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2926 for (x = 0; x < 128; ++x)
2928 *ptr++ = D3DCOLOR_ARGB(0xff, x * 2, y * 2, 0);
2931 else
2932 { /* Set up a displacement map which points away from the center parallel to the closest axis.
2933 * (if multiplied with bumpenvmat)
2935 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2936 for (x = 0; x < 128; ++x)
2938 if(abs(x-64)>abs(y-64))
2940 if(x < 64)
2941 *ptr++ = 0xc000;
2942 else
2943 *ptr++ = 0x4000;
2945 else
2947 if(y < 64)
2948 *ptr++ = 0x0040;
2949 else
2950 *ptr++ = 0x00c0;
2955 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
2956 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2958 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
2959 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2961 /* Disable texture filtering */
2962 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2963 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2964 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2965 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2967 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2968 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
2969 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2970 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
2974 /* Test the behavior of the texbem instruction with normal 2D and projective
2975 * 2D textures. */
2976 static void texbem_test(void)
2978 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
2979 /* Use asymmetric matrix to test loading. */
2980 float bumpenvmat[4] = {0.0f, 0.5f, -0.5f, 0.0f};
2981 IDirect3DPixelShader9 *pixel_shader = NULL;
2982 IDirect3DTexture9 *texture1, *texture2;
2983 IDirect3DTexture9 *texture = NULL;
2984 D3DLOCKED_RECT locked_rect;
2985 IDirect3DDevice9 *device;
2986 IDirect3D9 *d3d;
2987 ULONG refcount;
2988 D3DCAPS9 caps;
2989 DWORD color;
2990 HWND window;
2991 HRESULT hr;
2992 int i;
2994 static const DWORD pixel_shader_code[] =
2996 0xffff0101, /* ps_1_1*/
2997 0x00000042, 0xb00f0000, /* tex t0*/
2998 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
2999 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
3000 0x0000ffff
3002 static const DWORD double_texbem_code[] =
3004 0xffff0103, /* ps_1_3 */
3005 0x00000042, 0xb00f0000, /* tex t0 */
3006 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
3007 0x00000042, 0xb00f0002, /* tex t2 */
3008 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
3009 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
3010 0x0000ffff /* end */
3012 static const float quad[][7] =
3014 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
3015 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
3016 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
3017 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
3019 static const float quad_proj[][9] =
3021 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
3022 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
3023 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
3024 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
3026 static const float double_quad[] =
3028 -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3029 -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3030 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3031 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3033 static const D3DVERTEXELEMENT9 decl_elements[][4] =
3036 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3037 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3038 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
3039 D3DDECL_END()
3042 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3043 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3044 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
3045 D3DDECL_END()
3049 window = create_window();
3050 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3051 ok(!!d3d, "Failed to create a D3D object.\n");
3052 if (!(device = create_device(d3d, window, window, TRUE)))
3054 skip("Failed to create a D3D device, skipping tests.\n");
3055 goto done;
3058 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3059 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3060 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
3062 skip("No ps_1_1 support, skipping tests.\n");
3063 IDirect3DDevice9_Release(device);
3064 goto done;
3067 generate_bumpmap_textures(device);
3069 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
3070 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
3071 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
3072 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
3073 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
3075 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
3076 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
3078 for(i=0; i<2; i++)
3080 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
3081 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
3083 if(i)
3085 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
3086 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
3089 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
3090 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
3091 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
3092 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
3094 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
3095 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
3096 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
3097 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3099 hr = IDirect3DDevice9_BeginScene(device);
3100 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
3102 if(!i)
3103 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
3104 else
3105 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
3106 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
3108 hr = IDirect3DDevice9_EndScene(device);
3109 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
3111 /* The Window 8 testbot (WARP) seems to use the transposed
3112 * D3DTSS_BUMPENVMAT matrix. */
3113 color = getPixelColor(device, 160, 240);
3114 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00007e00, 4)),
3115 "Got unexpected color 0x%08x.\n", color);
3116 color = getPixelColor(device, 480, 240);
3117 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00fe7e00, 4)),
3118 "Got unexpected color 0x%08x.\n", color);
3119 color = getPixelColor(device, 320, 120);
3120 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x0080fe00, 4)),
3121 "Got unexpected color 0x%08x.\n", color);
3122 color = getPixelColor(device, 320, 360);
3123 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00800000, 4)),
3124 "Got unexpected color 0x%08x.\n", color);
3126 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3127 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3129 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3130 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3131 IDirect3DPixelShader9_Release(pixel_shader);
3133 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3134 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
3135 IDirect3DVertexDeclaration9_Release(vertex_declaration);
3138 /* clean up */
3139 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
3140 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
3142 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3143 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
3145 for(i=0; i<2; i++)
3147 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
3148 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
3149 IDirect3DTexture9_Release(texture); /* For the GetTexture */
3150 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
3151 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
3152 IDirect3DTexture9_Release(texture);
3155 /* Test double texbem */
3156 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
3157 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
3158 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
3159 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
3160 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
3161 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
3162 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
3163 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
3165 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
3166 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3167 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
3168 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
3170 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3171 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3173 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
3174 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3175 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
3176 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
3177 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
3178 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3181 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
3182 #define tex 0x00ff0000
3183 #define tex1 0x0000ff00
3184 #define origin 0x000000ff
3185 static const DWORD pixel_data[] = {
3186 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3187 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3188 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3189 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3190 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
3191 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3192 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3193 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3195 #undef tex1
3196 #undef tex2
3197 #undef origin
3199 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
3200 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3201 for(i = 0; i < 8; i++) {
3202 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
3204 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
3205 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3208 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3209 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3210 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
3211 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3212 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
3213 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3214 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
3215 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3216 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
3217 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
3218 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
3219 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
3221 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
3222 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
3223 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
3224 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3225 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
3226 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3227 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
3228 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3229 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
3230 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3232 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
3233 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
3234 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
3235 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3236 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
3237 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3238 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
3239 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3240 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
3241 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3243 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3244 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3245 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3246 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3247 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3248 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3249 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3250 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3251 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3252 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3253 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3254 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3255 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3256 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3257 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3258 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3260 hr = IDirect3DDevice9_BeginScene(device);
3261 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3262 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
3263 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
3264 hr = IDirect3DDevice9_EndScene(device);
3265 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3266 /* The Window 8 testbot (WARP) seems to use the transposed
3267 * D3DTSS_BUMPENVMAT matrix. */
3268 color = getPixelColor(device, 320, 240);
3269 ok(color_match(color, 0x00ffff00, 1) || broken(color_match(color, 0x0000ffff, 1)),
3270 "Got unexpected color 0x%08x.\n", color);
3272 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3273 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3275 IDirect3DPixelShader9_Release(pixel_shader);
3276 IDirect3DTexture9_Release(texture);
3277 IDirect3DTexture9_Release(texture1);
3278 IDirect3DTexture9_Release(texture2);
3279 refcount = IDirect3DDevice9_Release(device);
3280 ok(!refcount, "Device has %u references left.\n", refcount);
3281 done:
3282 IDirect3D9_Release(d3d);
3283 DestroyWindow(window);
3286 static void z_range_test(void)
3288 IDirect3DVertexShader9 *shader;
3289 IDirect3DDevice9 *device;
3290 IDirect3D9 *d3d;
3291 ULONG refcount;
3292 D3DCAPS9 caps;
3293 DWORD color;
3294 HWND window;
3295 HRESULT hr;
3297 static const struct
3299 struct vec3 position;
3300 DWORD diffuse;
3302 quad[] =
3304 {{-1.0f, 0.0f, 1.1f}, 0xffff0000},
3305 {{-1.0f, 1.0f, 1.1f}, 0xffff0000},
3306 {{ 1.0f, 0.0f, -1.1f}, 0xffff0000},
3307 {{ 1.0f, 1.0f, -1.1f}, 0xffff0000},
3309 quad2[] =
3311 {{-1.0f, 0.0f, 1.1f}, 0xff0000ff},
3312 {{-1.0f, 1.0f, 1.1f}, 0xff0000ff},
3313 {{ 1.0f, 0.0f, -1.1f}, 0xff0000ff},
3314 {{ 1.0f, 1.0f, -1.1f}, 0xff0000ff},
3316 static const struct
3318 struct vec4 position;
3319 DWORD diffuse;
3321 quad3[] =
3323 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xffffff00},
3324 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xffffff00},
3325 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xffffff00},
3326 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xffffff00},
3328 quad4[] =
3330 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xff00ff00},
3331 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xff00ff00},
3332 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xff00ff00},
3333 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xff00ff00},
3335 static const DWORD shader_code[] =
3337 0xfffe0101, /* vs_1_1 */
3338 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
3339 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
3340 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
3341 0x0000ffff /* end */
3343 static const float color_const_1[] = {1.0f, 0.0f, 0.0f, 1.0f};
3344 static const float color_const_2[] = {0.0f, 0.0f, 1.0f, 1.0f};
3346 window = create_window();
3347 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3348 ok(!!d3d, "Failed to create a D3D object.\n");
3349 if (!(device = create_device(d3d, window, window, TRUE)))
3351 skip("Failed to create a D3D device, skipping tests.\n");
3352 goto done;
3355 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3356 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3358 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
3359 * then call Present. Then clear the color buffer to make sure it has some defined content
3360 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
3361 * by the depth value. */
3362 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75f, 0);
3363 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3364 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3365 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
3366 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
3367 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3369 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3370 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
3371 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
3372 ok(SUCCEEDED(hr), "Failed to enable clipping, hr %#x.\n", hr);
3373 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3374 ok(SUCCEEDED(hr), "Failed to enable z test, hr %#x.\n", hr);
3375 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3376 ok(SUCCEEDED(hr), "Failed to disable z writes, hr %#x.\n", hr);
3377 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3378 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3379 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3380 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
3382 hr = IDirect3DDevice9_BeginScene(device);
3383 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3385 /* Test the untransformed vertex path */
3386 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
3387 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3388 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
3389 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3390 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
3391 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3393 /* Test the transformed vertex path */
3394 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
3395 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
3397 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
3398 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3399 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3400 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3401 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
3402 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3404 hr = IDirect3DDevice9_EndScene(device);
3405 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3407 /* Do not test the exact corner pixels, but go pretty close to them */
3409 /* Clipped because z > 1.0 */
3410 color = getPixelColor(device, 28, 238);
3411 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3412 color = getPixelColor(device, 28, 241);
3413 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
3414 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3415 else
3416 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
3418 /* Not clipped, > z buffer clear value(0.75).
3420 * On the r500 driver on Windows D3DCMP_GREATER and D3DCMP_GREATEREQUAL are broken for depth
3421 * values > 0.5. The range appears to be distorted, apparently an incoming value of ~0.875 is
3422 * equal to a stored depth buffer value of 0.5. */
3423 color = getPixelColor(device, 31, 238);
3424 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3425 color = getPixelColor(device, 31, 241);
3426 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
3427 color = getPixelColor(device, 100, 238);
3428 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
3429 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3430 color = getPixelColor(device, 100, 241);
3431 ok(color_match(color, 0x00ffff00, 0) || broken(color_match(color, 0x00ffffff, 0)),
3432 "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
3434 /* Not clipped, < z buffer clear value */
3435 color = getPixelColor(device, 104, 238);
3436 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3437 color = getPixelColor(device, 104, 241);
3438 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
3439 color = getPixelColor(device, 318, 238);
3440 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3441 color = getPixelColor(device, 318, 241);
3442 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
3444 /* Clipped because z < 0.0 */
3445 color = getPixelColor(device, 321, 238);
3446 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3447 color = getPixelColor(device, 321, 241);
3448 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
3449 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3450 else
3451 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3453 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3454 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
3456 /* Test the shader path */
3457 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
3459 skip("Vertex shaders not supported, skipping tests.\n");
3460 IDirect3DDevice9_Release(device);
3461 goto done;
3463 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
3464 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
3466 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
3467 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3469 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3470 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
3471 hr = IDirect3DDevice9_SetVertexShader(device, shader);
3472 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
3474 hr = IDirect3DDevice9_BeginScene(device);
3475 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3477 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, color_const_1, 1);
3478 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
3479 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
3480 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3482 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
3483 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3484 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, color_const_2, 1);
3485 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
3486 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
3487 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3489 hr = IDirect3DDevice9_EndScene(device);
3490 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3492 IDirect3DVertexShader9_Release(shader);
3494 /* Z < 1.0 */
3495 color = getPixelColor(device, 28, 238);
3496 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3498 /* 1.0 < z < 0.75 */
3499 color = getPixelColor(device, 31, 238);
3500 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3501 color = getPixelColor(device, 100, 238);
3502 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
3503 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3505 /* 0.75 < z < 0.0 */
3506 color = getPixelColor(device, 104, 238);
3507 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3508 color = getPixelColor(device, 318, 238);
3509 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3511 /* 0.0 < z */
3512 color = getPixelColor(device, 321, 238);
3513 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3515 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3516 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
3518 refcount = IDirect3DDevice9_Release(device);
3519 ok(!refcount, "Device has %u references left.\n", refcount);
3520 done:
3521 IDirect3D9_Release(d3d);
3522 DestroyWindow(window);
3525 static void fill_surface(IDirect3DSurface9 *surface, DWORD color, DWORD flags)
3527 D3DSURFACE_DESC desc;
3528 D3DLOCKED_RECT l;
3529 HRESULT hr;
3530 unsigned int x, y;
3531 DWORD *mem;
3533 memset(&desc, 0, sizeof(desc));
3534 memset(&l, 0, sizeof(l));
3535 hr = IDirect3DSurface9_GetDesc(surface, &desc);
3536 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
3537 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, flags);
3538 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
3539 if(FAILED(hr)) return;
3541 for(y = 0; y < desc.Height; y++)
3543 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
3544 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
3546 mem[x] = color;
3549 hr = IDirect3DSurface9_UnlockRect(surface);
3550 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
3553 static void stretchrect_test(void)
3555 IDirect3DSurface9 *surf_tex_rt32, *surf_tex_rt64, *surf_tex_rt_dest64, *surf_tex_rt_dest640_480;
3556 IDirect3DSurface9 *surf_offscreen32, *surf_offscreen64, *surf_offscreen_dest64;
3557 IDirect3DTexture9 *tex_rt32, *tex_rt64, *tex_rt_dest64, *tex_rt_dest640_480;
3558 IDirect3DSurface9 *surf_tex32, *surf_tex64, *surf_tex_dest64;
3559 IDirect3DSurface9 *surf_rt32, *surf_rt64, *surf_rt_dest64;
3560 IDirect3DTexture9 *tex32, *tex64, *tex_dest64;
3561 IDirect3DSurface9 *surf_temp32, *surf_temp64;
3562 IDirect3DSurface9 *backbuffer;
3563 IDirect3DDevice9 *device;
3564 IDirect3D9 *d3d;
3565 D3DCOLOR color;
3566 ULONG refcount;
3567 HWND window;
3568 HRESULT hr;
3570 static const RECT src_rect = {0, 0, 640, 480};
3571 static const RECT src_rect_flipy = {0, 480, 640, 0};
3572 static const RECT dst_rect = {0, 0, 640, 480};
3573 static const RECT dst_rect_flipy = {0, 480, 640, 0};
3574 static const RECT src_rect64 = {0, 0, 64, 64};
3575 static const RECT src_rect64_flipy = {0, 64, 64, 0};
3576 static const RECT dst_rect64 = {0, 0, 64, 64};
3577 static const RECT dst_rect64_flipy = {0, 64, 64, 0};
3579 window = create_window();
3580 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3581 ok(!!d3d, "Failed to create a D3D object.\n");
3582 if (!(device = create_device(d3d, window, window, TRUE)))
3584 skip("Failed to create a D3D device, skipping tests.\n");
3585 goto done;
3588 /* Create our temporary surfaces in system memory. */
3589 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
3590 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
3591 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3592 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
3593 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
3594 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3596 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT. */
3597 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
3598 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
3599 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3600 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
3601 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
3602 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3603 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
3604 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
3605 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3607 /* Create render target surfaces. */
3608 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32,
3609 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
3610 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
3611 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64,
3612 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
3613 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
3614 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64,
3615 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
3616 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
3617 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
3618 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
3620 /* Create render target textures. */
3621 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET,
3622 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
3623 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3624 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET,
3625 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
3626 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3627 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET,
3628 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
3629 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3630 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET,
3631 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
3632 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3633 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
3634 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3635 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
3636 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3637 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
3638 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3639 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
3640 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3642 /* Create regular textures in D3DPOOL_DEFAULT. */
3643 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
3644 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3645 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
3646 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3647 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
3648 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3649 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
3650 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3651 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
3652 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3653 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
3654 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3656 /**********************************************************************
3657 * Tests for when the source parameter is an offscreen plain surface. *
3658 **********************************************************************/
3660 /* Fill the offscreen 64x64 surface with green. */
3661 fill_surface(surf_offscreen64, 0xff00ff00, 0);
3663 /* offscreenplain ==> offscreenplain, same size. */
3664 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, D3DTEXF_NONE);
3665 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3666 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
3667 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
3668 /* Blit without scaling. */
3669 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3670 surf_offscreen_dest64, &dst_rect64, D3DTEXF_NONE);
3671 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3672 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3673 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy,
3674 surf_offscreen_dest64, &dst_rect64, D3DTEXF_NONE);
3675 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3676 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3677 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3678 surf_offscreen_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3679 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3681 /* offscreenplain ==> rendertarget texture, same size. */
3682 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3683 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3684 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3685 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3686 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3687 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3688 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
3689 /* Blit without scaling. */
3690 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3691 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3692 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3693 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3694 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy,
3695 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3696 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3697 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3698 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3699 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3700 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3702 /* offscreenplain ==> rendertarget surface, same size. */
3703 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3704 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3705 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3706 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
3707 /* Blit without scaling. */
3708 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3709 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3710 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3711 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3712 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy,
3713 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3714 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3715 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3716 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3717 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3718 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3720 /* offscreenplain ==> texture, same size (should fail). */
3721 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3722 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3724 /* Fill the smaller offscreen surface with red. */
3725 fill_surface(surf_offscreen32, 0xffff0000, 0);
3727 /* offscreenplain ==> offscreenplain, scaling (should fail). */
3728 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3729 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3731 /* offscreenplain ==> rendertarget texture, scaling. */
3732 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3733 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3734 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3735 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3736 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3737 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3738 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3740 /* offscreenplain ==> rendertarget surface, scaling. */
3741 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3742 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3743 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3744 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3746 /* offscreenplain ==> texture, scaling (should fail). */
3747 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3748 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3750 /*************************************************************
3751 * Tests for when the source parameter is a regular texture. *
3752 *************************************************************/
3754 /* Fill the surface of the regular texture with blue. */
3755 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT. */
3756 fill_surface(surf_temp64, 0xff0000ff, 0);
3757 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
3758 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3760 /* texture ==> offscreenplain, same size. */
3761 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3762 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3764 /* texture ==> rendertarget texture, same size. */
3765 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3766 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3767 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3768 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3769 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3770 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3771 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
3772 /* Blit without scaling. */
3773 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3774 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3775 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3776 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3777 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy,
3778 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3779 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3780 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3781 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3782 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3783 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3785 /* texture ==> rendertarget surface, same size. */
3786 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3787 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3788 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3789 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
3790 /* Blit without scaling. */
3791 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3792 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3793 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3794 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3795 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy,
3796 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3797 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3798 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3799 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3800 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3801 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3803 /* texture ==> texture, same size (should fail). */
3804 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3805 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3807 /* Fill the surface of the smaller regular texture with red. */
3808 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT. */
3809 fill_surface(surf_temp32, 0xffff0000, 0);
3810 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
3811 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3813 /* texture ==> offscreenplain, scaling (should fail). */
3814 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3815 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3817 /* texture ==> rendertarget texture, scaling. */
3818 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3819 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3820 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3821 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3822 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3823 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3824 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3826 /* texture ==> rendertarget surface, scaling. */
3827 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3828 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3829 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3830 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3832 /* texture ==> texture, scaling (should fail). */
3833 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3834 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3836 /******************************************************************
3837 * Tests for when the source parameter is a rendertarget texture. *
3838 ******************************************************************/
3840 /* Fill the surface of the rendertarget texture with white. */
3841 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT. */
3842 fill_surface(surf_temp64, 0xffffffff, 0);
3843 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
3844 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3846 /* rendertarget texture ==> offscreenplain, same size. */
3847 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3848 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3850 /* rendertarget texture ==> rendertarget texture, same size. */
3851 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3852 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3853 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3854 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3855 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3856 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3857 ok(color == 0xffffffff, "Got unexpected color 0x%08x.\n", color);
3858 /* Blit without scaling. */
3859 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3860 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3861 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3862 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3863 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy,
3864 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3865 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3866 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3867 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3868 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3869 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3871 /* rendertarget texture ==> rendertarget surface, same size. */
3872 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3873 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3874 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3875 ok(color == 0xffffffff, "Got unexpected color 0x%08x.\n", color);
3876 /* Blit without scaling. */
3877 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3878 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3879 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3880 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3881 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy,
3882 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3883 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3884 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3885 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3886 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3887 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3889 /* rendertarget texture ==> texture, same size (should fail). */
3890 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3891 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3893 /* Fill the surface of the smaller rendertarget texture with red. */
3894 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT. */
3895 fill_surface(surf_temp32, 0xffff0000, 0);
3896 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
3897 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3899 /* rendertarget texture ==> offscreenplain, scaling (should fail). */
3900 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3901 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3903 /* rendertarget texture ==> rendertarget texture, scaling. */
3904 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3905 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3906 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3907 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3908 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3909 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3910 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3912 /* rendertarget texture ==> rendertarget surface, scaling. */
3913 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3914 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3915 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3916 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3918 /* rendertarget texture ==> texture, scaling (should fail). */
3919 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3920 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3922 /******************************************************************
3923 * Tests for when the source parameter is a rendertarget surface. *
3924 ******************************************************************/
3926 /* Fill the surface of the rendertarget surface with black. */
3927 fill_surface(surf_rt64, 0xff000000, 0);
3929 /* rendertarget texture ==> offscreenplain, same size. */
3930 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3931 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3933 /* rendertarget surface ==> rendertarget texture, same size. */
3934 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3935 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3936 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3937 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3938 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3939 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3940 ok(color == 0xff000000, "Got unexpected color 0x%08x.\n", color);
3941 /* Blit without scaling. */
3942 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3943 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3944 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3945 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3946 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy,
3947 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3948 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3949 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3950 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3951 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3952 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3954 /* rendertarget surface ==> rendertarget surface, same size. */
3955 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3956 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3957 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3958 ok(color == 0xff000000, "Got unexpected color 0x%08x.\n", color);
3959 /* Blit without scaling. */
3960 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3961 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3962 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3963 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3964 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy,
3965 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3966 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3967 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3968 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3969 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3970 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3972 /* rendertarget surface ==> texture, same size (should fail). */
3973 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3974 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3976 /* Fill the surface of the smaller rendertarget texture with red. */
3977 fill_surface(surf_rt32, 0xffff0000, 0);
3979 /* rendertarget surface ==> offscreenplain, scaling (should fail). */
3980 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3981 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3983 /* rendertarget surface ==> rendertarget texture, scaling. */
3984 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3985 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3986 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3987 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3988 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3989 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3990 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3992 /* rendertarget surface ==> rendertarget surface, scaling. */
3993 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3994 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3995 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3996 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3998 /* rendertarget surface ==> texture, scaling (should fail). */
3999 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
4000 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4002 /* backbuffer ==> surface tests (no scaling). */
4003 /* Blit with NULL rectangles. */
4004 hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, D3DTEXF_NONE);
4005 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4006 /* Blit without scaling. */
4007 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect,
4008 surf_tex_rt_dest640_480, &dst_rect, D3DTEXF_NONE);
4009 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4010 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
4011 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy,
4012 surf_tex_rt_dest640_480, &dst_rect, D3DTEXF_NONE);
4013 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4014 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
4015 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect,
4016 surf_tex_rt_dest640_480, &dst_rect_flipy, D3DTEXF_NONE);
4017 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4019 /* TODO: Test format conversions. */
4021 IDirect3DSurface9_Release(backbuffer);
4022 IDirect3DSurface9_Release(surf_rt32);
4023 IDirect3DSurface9_Release(surf_rt64);
4024 IDirect3DSurface9_Release(surf_rt_dest64);
4025 IDirect3DSurface9_Release(surf_temp32);
4026 IDirect3DSurface9_Release(surf_temp64);
4027 IDirect3DSurface9_Release(surf_offscreen32);
4028 IDirect3DSurface9_Release(surf_offscreen64);
4029 IDirect3DSurface9_Release(surf_offscreen_dest64);
4030 IDirect3DSurface9_Release(surf_tex_rt32);
4031 IDirect3DTexture9_Release(tex_rt32);
4032 IDirect3DSurface9_Release(surf_tex_rt64);
4033 IDirect3DTexture9_Release(tex_rt64);
4034 IDirect3DSurface9_Release(surf_tex_rt_dest64);
4035 IDirect3DTexture9_Release(tex_rt_dest64);
4036 IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
4037 IDirect3DTexture9_Release(tex_rt_dest640_480);
4038 IDirect3DSurface9_Release(surf_tex32);
4039 IDirect3DTexture9_Release(tex32);
4040 IDirect3DSurface9_Release(surf_tex64);
4041 IDirect3DTexture9_Release(tex64);
4042 IDirect3DSurface9_Release(surf_tex_dest64);
4043 IDirect3DTexture9_Release(tex_dest64);
4044 refcount = IDirect3DDevice9_Release(device);
4045 ok(!refcount, "Device has %u references left.\n", refcount);
4046 done:
4047 IDirect3D9_Release(d3d);
4048 DestroyWindow(window);
4051 static void maxmip_test(void)
4053 IDirect3DTexture9 *texture;
4054 IDirect3DSurface9 *surface;
4055 IDirect3DDevice9 *device;
4056 IDirect3D9 *d3d;
4057 D3DCOLOR color;
4058 ULONG refcount;
4059 D3DCAPS9 caps;
4060 HWND window;
4061 HRESULT hr;
4062 DWORD ret;
4064 static const struct
4066 struct
4068 float x, y, z;
4069 float s, t;
4071 v[4];
4073 quads[] =
4076 {-1.0, -1.0, 0.0, 0.0, 0.0},
4077 {-1.0, 0.0, 0.0, 0.0, 1.0},
4078 { 0.0, -1.0, 0.0, 1.0, 0.0},
4079 { 0.0, 0.0, 0.0, 1.0, 1.0},
4082 { 0.0, -1.0, 0.0, 0.0, 0.0},
4083 { 0.0, 0.0, 0.0, 0.0, 1.0},
4084 { 1.0, -1.0, 0.0, 1.0, 0.0},
4085 { 1.0, 0.0, 0.0, 1.0, 1.0},
4088 { 0.0, 0.0, 0.0, 0.0, 0.0},
4089 { 0.0, 1.0, 0.0, 0.0, 1.0},
4090 { 1.0, 0.0, 0.0, 1.0, 0.0},
4091 { 1.0, 1.0, 0.0, 1.0, 1.0},
4094 {-1.0, 0.0, 0.0, 0.0, 0.0},
4095 {-1.0, 1.0, 0.0, 0.0, 1.0},
4096 { 0.0, 0.0, 0.0, 1.0, 0.0},
4097 { 0.0, 1.0, 0.0, 1.0, 1.0},
4101 window = create_window();
4102 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4103 ok(!!d3d, "Failed to create a D3D object.\n");
4104 if (!(device = create_device(d3d, window, window, TRUE)))
4106 skip("Failed to create a D3D device, skipping tests.\n");
4107 goto done;
4110 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4111 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4112 if (!(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP))
4114 skip("No mipmap support, skipping tests.\n");
4115 IDirect3DDevice9_Release(device);
4116 goto done;
4119 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0,
4120 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
4121 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
4123 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4124 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
4125 fill_surface(surface, 0xffff0000, 0);
4126 IDirect3DSurface9_Release(surface);
4127 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
4128 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
4129 fill_surface(surface, 0xff00ff00, 0);
4130 IDirect3DSurface9_Release(surface);
4131 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
4132 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
4133 fill_surface(surface, 0xff0000ff, 0);
4134 IDirect3DSurface9_Release(surface);
4136 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4137 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4138 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4139 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4141 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4142 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4143 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4144 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4146 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
4147 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4149 hr = IDirect3DDevice9_BeginScene(device);
4150 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4152 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
4153 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4154 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
4155 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4157 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
4158 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4159 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
4160 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4162 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4163 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4164 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
4165 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4167 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
4168 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4169 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
4170 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4172 hr = IDirect3DDevice9_EndScene(device);
4173 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4175 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
4176 color = getPixelColor(device, 160, 360);
4177 ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
4178 color = getPixelColor(device, 480, 360);
4179 ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
4180 color = getPixelColor(device, 480, 120);
4181 ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
4182 color = getPixelColor(device, 160, 120);
4183 ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
4184 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4185 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4187 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4188 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4190 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
4191 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4193 hr = IDirect3DDevice9_BeginScene(device);
4194 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4196 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
4197 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4198 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
4199 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4201 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
4202 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4203 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
4204 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4206 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4207 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4208 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
4209 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4211 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
4212 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4213 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
4214 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4216 hr = IDirect3DDevice9_EndScene(device);
4217 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4219 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
4220 * level 3 (> levels in texture) samples from the highest level in the
4221 * texture (level 2). */
4222 color = getPixelColor(device, 160, 360);
4223 ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
4224 color = getPixelColor(device, 480, 360);
4225 ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
4226 color = getPixelColor(device, 480, 120);
4227 ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
4228 color = getPixelColor(device, 160, 120);
4229 ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
4230 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4231 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4233 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
4234 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4236 hr = IDirect3DDevice9_BeginScene(device);
4237 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4239 /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
4240 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4241 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4242 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
4243 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4244 ret = IDirect3DTexture9_SetLOD(texture, 1);
4245 ok(ret == 0, "Got unexpected LOD %u.\n", ret);
4246 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
4247 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4249 /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
4250 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4251 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4252 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
4253 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4254 ret = IDirect3DTexture9_SetLOD(texture, 2);
4255 ok(ret == 1, "Got unexpected LOD %u.\n", ret);
4256 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
4257 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4259 /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
4260 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4261 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4262 ret = IDirect3DTexture9_SetLOD(texture, 1);
4263 ok(ret == 2, "Got unexpected LOD %u.\n", ret);
4264 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
4265 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4267 /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
4268 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4269 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4270 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4271 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4272 ret = IDirect3DTexture9_SetLOD(texture, 1);
4273 ok(ret == 1, "Got unexpected LOD %u.\n", ret);
4274 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
4275 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4277 hr = IDirect3DDevice9_EndScene(device);
4278 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4280 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
4281 * level 3 (> levels in texture) samples from the highest level in the
4282 * texture (level 2). */
4283 color = getPixelColor(device, 160, 360);
4284 ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
4285 color = getPixelColor(device, 480, 360);
4286 ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
4287 color = getPixelColor(device, 480, 120);
4288 ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
4289 color = getPixelColor(device, 160, 120);
4290 ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
4292 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4293 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4295 IDirect3DTexture9_Release(texture);
4296 refcount = IDirect3DDevice9_Release(device);
4297 ok(!refcount, "Device has %u references left.\n", refcount);
4298 done:
4299 IDirect3D9_Release(d3d);
4300 DestroyWindow(window);
4303 static void release_buffer_test(void)
4305 IDirect3DVertexBuffer9 *vb;
4306 IDirect3DIndexBuffer9 *ib;
4307 IDirect3DDevice9 *device;
4308 IDirect3D9 *d3d;
4309 D3DCOLOR color;
4310 ULONG refcount;
4311 HWND window;
4312 HRESULT hr;
4313 BYTE *data;
4314 LONG ref;
4316 static const short indices[] = {3, 4, 5};
4317 static const struct
4319 struct vec3 position;
4320 DWORD diffuse;
4322 quad[] =
4324 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
4325 {{-1.0f, 1.0f, 0.1f}, 0xffff0000},
4326 {{ 1.0f, 1.0f, 0.1f}, 0xffff0000},
4328 {{-1.0f, -1.0f, 0.1f}, 0xff00ff00},
4329 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
4330 {{ 1.0f, 1.0f, 0.1f}, 0xff00ff00},
4333 window = create_window();
4334 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4335 ok(!!d3d, "Failed to create a D3D object.\n");
4336 if (!(device = create_device(d3d, window, window, TRUE)))
4338 skip("Failed to create a D3D device, skipping tests.\n");
4339 goto done;
4342 /* Index and vertex buffers should always be creatable */
4343 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0,
4344 D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &vb, NULL);
4345 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
4346 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
4347 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
4348 memcpy(data, quad, sizeof(quad));
4349 hr = IDirect3DVertexBuffer9_Unlock(vb);
4350 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
4352 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0,
4353 D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
4354 ok(SUCCEEDED(hr), "Failed to create index buffer, hr %#x.\n", hr);
4355 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
4356 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
4357 memcpy(data, indices, sizeof(indices));
4358 hr = IDirect3DIndexBuffer9_Unlock(ib);
4359 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
4361 hr = IDirect3DDevice9_SetIndices(device, ib);
4362 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
4363 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
4364 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
4365 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
4366 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4367 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4368 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4370 /* Now destroy the bound index buffer and draw again */
4371 ref = IDirect3DIndexBuffer9_Release(ib);
4372 ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
4374 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4375 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
4377 hr = IDirect3DDevice9_BeginScene(device);
4378 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4379 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent
4380 * D3D from making assumptions about the indices or vertices. */
4381 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
4382 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4383 hr = IDirect3DDevice9_EndScene(device);
4384 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4386 color = getPixelColor(device, 160, 120);
4387 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1), "Got unexpected color 0x%08x.\n", color);
4388 color = getPixelColor(device, 480, 360);
4389 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1), "Got unexpected color 0x%08x.\n", color);
4391 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4392 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4394 /* Index buffer was already destroyed as part of the test */
4395 IDirect3DVertexBuffer9_Release(vb);
4396 refcount = IDirect3DDevice9_Release(device);
4397 ok(!refcount, "Device has %u references left.\n", refcount);
4398 done:
4399 IDirect3D9_Release(d3d);
4400 DestroyWindow(window);
4403 static void float_texture_test(void)
4405 IDirect3DTexture9 *texture;
4406 IDirect3DDevice9 *device;
4407 D3DLOCKED_RECT lr;
4408 IDirect3D9 *d3d;
4409 ULONG refcount;
4410 float *data;
4411 DWORD color;
4412 HWND window;
4413 HRESULT hr;
4415 static const float quad[] =
4417 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
4418 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
4419 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
4420 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4423 window = create_window();
4424 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4425 ok(!!d3d, "Failed to create a D3D object.\n");
4426 if (!(device = create_device(d3d, window, window, TRUE)))
4428 skip("Failed to create a D3D device, skipping tests.\n");
4429 goto done;
4432 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
4433 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK)
4435 skip("D3DFMT_R32F textures not supported\n");
4436 IDirect3DDevice9_Release(device);
4437 goto done;
4440 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F, D3DPOOL_MANAGED, &texture, NULL);
4441 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
4443 memset(&lr, 0, sizeof(lr));
4444 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4445 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
4446 data = lr.pBits;
4447 *data = 0.0;
4448 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4449 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
4451 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4452 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4453 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
4454 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4456 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4457 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
4459 hr = IDirect3DDevice9_BeginScene(device);
4460 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4461 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4462 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4463 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4464 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4465 hr = IDirect3DDevice9_EndScene(device);
4466 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4468 color = getPixelColor(device, 240, 320);
4469 ok(color == 0x0000ffff, "R32F with value 0.0 has color %08x, expected 0x0000ffff\n", color);
4471 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4472 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4474 IDirect3DTexture9_Release(texture);
4475 refcount = IDirect3DDevice9_Release(device);
4476 ok(!refcount, "Device has %u references left.\n", refcount);
4477 done:
4478 IDirect3D9_Release(d3d);
4479 DestroyWindow(window);
4482 static void g16r16_texture_test(void)
4484 IDirect3DTexture9 *texture;
4485 IDirect3DDevice9 *device;
4486 D3DLOCKED_RECT lr;
4487 IDirect3D9 *d3d;
4488 ULONG refcount;
4489 DWORD *data;
4490 DWORD color;
4491 HWND window;
4492 HRESULT hr;
4494 static const float quad[] =
4496 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
4497 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
4498 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
4499 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4502 window = create_window();
4503 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4504 ok(!!d3d, "Failed to create a D3D object.\n");
4505 if (!(device = create_device(d3d, window, window, TRUE)))
4507 skip("Failed to create a D3D device, skipping tests.\n");
4508 goto done;
4511 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
4512 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK)
4514 skip("D3DFMT_G16R16 textures not supported\n");
4515 IDirect3DDevice9_Release(device);
4516 goto done;
4519 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16, D3DPOOL_MANAGED, &texture, NULL);
4520 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
4522 memset(&lr, 0, sizeof(lr));
4523 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4524 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
4525 data = lr.pBits;
4526 *data = 0x0f00f000;
4527 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4528 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
4530 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4531 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4532 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
4533 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4535 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4536 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
4538 hr = IDirect3DDevice9_BeginScene(device);
4539 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4540 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4541 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4542 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4543 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4544 hr = IDirect3DDevice9_EndScene(device);
4545 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4547 color = getPixelColor(device, 240, 320);
4548 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
4549 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
4551 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4552 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4554 IDirect3DTexture9_Release(texture);
4555 refcount = IDirect3DDevice9_Release(device);
4556 ok(!refcount, "Device has %u references left.\n", refcount);
4557 done:
4558 IDirect3D9_Release(d3d);
4559 DestroyWindow(window);
4562 static void check_rect(IDirect3DDevice9 *device, RECT r, const char *message)
4564 LONG x_coords[2][2] =
4566 {r.left - 1, r.left + 1},
4567 {r.right + 1, r.right - 1},
4569 LONG y_coords[2][2] =
4571 {r.top - 1, r.top + 1},
4572 {r.bottom + 1, r.bottom - 1}
4574 unsigned int i, j, x_side, y_side;
4576 for (i = 0; i < 2; ++i)
4578 for (j = 0; j < 2; ++j)
4580 for (x_side = 0; x_side < 2; ++x_side)
4582 for (y_side = 0; y_side < 2; ++y_side)
4584 unsigned int x = x_coords[i][x_side], y = y_coords[j][y_side];
4585 DWORD color;
4586 DWORD expected = (x_side == 1 && y_side == 1) ? 0x00ffffff : 0;
4588 color = getPixelColor(device, x, y);
4589 ok(color == expected, "%s: Pixel (%d, %d) has color %08x, expected %08x\n",
4590 message, x, y, color, expected);
4597 struct projected_textures_test_run
4599 const char *message;
4600 DWORD flags;
4601 IDirect3DVertexDeclaration9 *decl;
4602 BOOL vs, ps;
4603 RECT rect;
4606 static void projected_textures_test(IDirect3DDevice9 *device,
4607 struct projected_textures_test_run tests[4])
4609 unsigned int i;
4611 static const DWORD vertex_shader[] =
4613 0xfffe0101, /* vs_1_1 */
4614 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4615 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
4616 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4617 0x00000001, 0xe00f0000, 0x90e40001, /* mov oT0, v1 */
4618 0x0000ffff /* end */
4620 static const DWORD pixel_shader[] =
4622 0xffff0103, /* ps_1_3 */
4623 0x00000042, 0xb00f0000, /* tex t0 */
4624 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4625 0x0000ffff /* end */
4627 IDirect3DVertexShader9 *vs = NULL;
4628 IDirect3DPixelShader9 *ps = NULL;
4629 IDirect3D9 *d3d;
4630 D3DCAPS9 caps;
4631 HRESULT hr;
4633 IDirect3DDevice9_GetDirect3D(device, &d3d);
4634 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4635 ok(SUCCEEDED(hr), "GetDeviceCaps failed (%08x)\n", hr);
4636 IDirect3D9_Release(d3d);
4638 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
4640 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader, &vs);
4641 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
4643 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 3))
4645 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader, &ps);
4646 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
4649 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0f, 0);
4650 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4652 hr = IDirect3DDevice9_BeginScene(device);
4653 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4655 for (i = 0; i < 4; ++i)
4657 DWORD value = 0xdeadbeef;
4658 static const float proj_quads[] =
4660 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4661 -1.0f, 0.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4662 0.0f, -1.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4663 0.0f, 0.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4665 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4666 0.0f, 0.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4667 1.0f, -1.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4668 1.0f, 0.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4670 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4671 -1.0f, 1.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4672 0.0f, 0.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4673 0.0f, 1.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4675 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4676 0.0f, 1.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4677 1.0f, 0.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4678 1.0f, 1.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4681 if (tests[i].vs)
4683 if (!vs)
4685 skip("Vertex shaders not supported, skipping\n");
4686 continue;
4688 hr = IDirect3DDevice9_SetVertexShader(device, vs);
4690 else
4691 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4692 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
4693 if (tests[i].ps)
4695 if (!ps)
4697 skip("Pixel shaders not supported, skipping\n");
4698 continue;
4700 hr = IDirect3DDevice9_SetPixelShader(device, ps);
4702 else
4703 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4704 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4706 hr = IDirect3DDevice9_SetVertexDeclaration(device, tests[i].decl);
4707 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4709 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, tests[i].flags);
4710 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4711 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, &value);
4712 ok(SUCCEEDED(hr) && value == tests[i].flags,
4713 "GetTextureStageState returned: hr %08x, value %08x.\n", hr, value);
4715 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
4716 &proj_quads[i * 4 * 7], 7 * sizeof(float));
4717 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4720 hr = IDirect3DDevice9_EndScene(device);
4721 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4723 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4724 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4725 if (vs) IDirect3DVertexShader9_Release(vs);
4726 if (ps) IDirect3DPixelShader9_Release(ps);
4728 for (i = 0; i < 4; ++i)
4730 if ((!tests[i].vs || vs) && (!tests[i].ps || ps))
4731 check_rect(device, tests[i].rect, tests[i].message);
4734 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4735 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4738 static void texture_transform_flags_test(void)
4740 HRESULT hr;
4741 IDirect3D9 *d3d;
4742 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
4743 D3DCAPS9 caps;
4744 IDirect3DTexture9 *texture = NULL;
4745 IDirect3DVolumeTexture9 *volume = NULL;
4746 IDirect3DDevice9 *device;
4747 unsigned int x, y, z;
4748 D3DLOCKED_RECT lr;
4749 D3DLOCKED_BOX lb;
4750 D3DCOLOR color;
4751 ULONG refcount;
4752 HWND window;
4753 UINT w, h;
4754 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3, *decl4;
4756 static const D3DVERTEXELEMENT9 decl_elements[] = {
4757 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4758 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4759 D3DDECL_END()
4761 static const D3DVERTEXELEMENT9 decl_elements2[] = {
4762 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4763 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4764 D3DDECL_END()
4766 static const D3DVERTEXELEMENT9 decl_elements3[] = {
4767 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4768 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4769 D3DDECL_END()
4771 static const D3DVERTEXELEMENT9 decl_elements4[] = {
4772 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4773 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4774 D3DDECL_END()
4776 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
4777 0x00, 0xff, 0x00, 0x00,
4778 0x00, 0x00, 0x00, 0x00,
4779 0x00, 0x00, 0x00, 0x00};
4780 static const D3DMATRIX identity =
4782 1.0f, 0.0f, 0.0f, 0.0f,
4783 0.0f, 1.0f, 0.0f, 0.0f,
4784 0.0f, 0.0f, 1.0f, 0.0f,
4785 0.0f, 0.0f, 0.0f, 1.0f,
4786 }}};
4788 window = create_window();
4789 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4790 ok(!!d3d, "Failed to create a D3D object.\n");
4791 if (!(device = create_device(d3d, window, window, TRUE)))
4793 skip("Failed to create a D3D device, skipping tests.\n");
4794 goto done;
4797 memset(&lr, 0, sizeof(lr));
4798 memset(&lb, 0, sizeof(lb));
4799 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
4800 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK)
4801 fmt = D3DFMT_A16B16G16R16;
4803 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4804 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4805 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
4806 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4807 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
4808 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4809 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements4, &decl4);
4810 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4811 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
4812 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
4813 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
4814 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
4815 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
4816 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
4817 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4818 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
4819 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
4820 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
4821 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
4822 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
4823 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
4824 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
4825 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
4826 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState(D3DTSS_COLOROP) returned %08x\n", hr);
4827 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
4828 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState(D3DTSS_COLORARG1) returned %08x\n", hr);
4829 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4830 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
4831 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4832 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4834 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4835 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
4836 w = min(1024, caps.MaxTextureWidth);
4837 h = min(1024, caps.MaxTextureHeight);
4838 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
4839 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
4840 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4841 if (!texture)
4843 skip("Failed to create the test texture.\n");
4844 IDirect3DDevice9_Release(device);
4845 goto done;
4848 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
4849 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
4850 * 1.0 in red and green for the x and y coords
4852 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4853 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
4854 for(y = 0; y < h; y++) {
4855 for(x = 0; x < w; x++) {
4856 double r_f = (double) y / (double) h;
4857 double g_f = (double) x / (double) w;
4858 if(fmt == D3DFMT_A16B16G16R16) {
4859 unsigned short r, g;
4860 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
4861 r = (unsigned short) (r_f * 65536.0);
4862 g = (unsigned short) (g_f * 65536.0);
4863 dst[0] = r;
4864 dst[1] = g;
4865 dst[2] = 0;
4866 dst[3] = 65535;
4867 } else {
4868 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
4869 unsigned char r = (unsigned char) (r_f * 255.0);
4870 unsigned char g = (unsigned char) (g_f * 255.0);
4871 dst[0] = 0;
4872 dst[1] = g;
4873 dst[2] = r;
4874 dst[3] = 255;
4878 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4879 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
4880 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4881 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4883 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4884 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4885 hr = IDirect3DDevice9_BeginScene(device);
4886 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4887 if(SUCCEEDED(hr))
4889 static const float quad1[] =
4891 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f,
4892 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4893 0.0f, -1.0f, 0.1f, 1.0f, 1.0f,
4894 0.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4896 static const float quad2[] =
4898 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4899 -1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4900 0.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4901 0.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4903 static const float quad3[] =
4905 0.0f, 0.0f, 0.1f, 0.5f, 0.5f,
4906 0.0f, 1.0f, 0.1f, 0.5f, 0.5f,
4907 1.0f, 0.0f, 0.1f, 0.5f, 0.5f,
4908 1.0f, 1.0f, 0.1f, 0.5f, 0.5f,
4910 static const float quad4[] =
4912 320.0f, 480.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4913 320.0f, 240.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4914 640.0f, 480.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4915 640.0f, 240.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4917 D3DMATRIX mat =
4919 0.0f, 0.0f, 0.0f, 0.0f,
4920 0.0f, 0.0f, 0.0f, 0.0f,
4921 0.0f, 0.0f, 0.0f, 0.0f,
4922 0.0f, 0.0f, 0.0f, 0.0f,
4923 }}};
4925 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
4926 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4927 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4928 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4929 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4931 /* What happens with transforms enabled? */
4932 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4933 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4934 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4935 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4937 /* What happens if 4 coords are used, but only 2 given ?*/
4938 U(mat).m[2][0] = 1.0f;
4939 U(mat).m[3][1] = 1.0f;
4940 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4941 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4942 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
4943 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4944 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4945 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4947 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
4948 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
4949 * due to the coords in the vertices. (turns out red, indeed)
4951 memset(&mat, 0, sizeof(mat));
4952 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4953 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4954 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
4955 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
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, quad4, 6 * sizeof(float));
4959 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4961 hr = IDirect3DDevice9_EndScene(device);
4962 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4964 color = getPixelColor(device, 160, 360);
4965 ok(color_match(color, 0x00ffff00, 1), "quad 1 has color %08x, expected 0x00ffff00\n", color);
4966 color = getPixelColor(device, 160, 120);
4967 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4968 color = getPixelColor(device, 480, 120);
4969 ok(color_match(color, 0x0000ff00, 1), "quad 3 has color %08x, expected 0x0000ff00\n", color);
4970 color = getPixelColor(device, 480, 360);
4971 ok(color_match(color, 0x00ff0000, 1), "quad 4 has color %08x, expected 0x00ff0000\n", color);
4972 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4973 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4975 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
4976 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4978 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4979 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4980 hr = IDirect3DDevice9_BeginScene(device);
4981 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4982 if(SUCCEEDED(hr))
4984 static const float quad1[] =
4986 -1.0f, -1.0f, 0.1f, 0.8f, 0.2f,
4987 -1.0f, 0.0f, 0.1f, 0.8f, 0.2f,
4988 0.0f, -1.0f, 0.1f, 0.8f, 0.2f,
4989 0.0f, 0.0f, 0.1f, 0.8f, 0.2f,
4991 static const float quad2[] =
4993 -1.0f, 0.0f, 0.1f, 0.5f, 1.0f,
4994 -1.0f, 1.0f, 0.1f, 0.5f, 1.0f,
4995 0.0f, 0.0f, 0.1f, 0.5f, 1.0f,
4996 0.0f, 1.0f, 0.1f, 0.5f, 1.0f,
4998 static const float quad3[] =
5000 0.0f, 0.0f, 0.1f, 0.5f, 1.0f,
5001 0.0f, 1.0f, 0.1f, 0.5f, 1.0f,
5002 1.0f, 0.0f, 0.1f, 0.5f, 1.0f,
5003 1.0f, 1.0f, 0.1f, 0.5f, 1.0f,
5005 static const float quad4[] =
5007 0.0f, -1.0f, 0.1f, 0.8f, 0.2f,
5008 0.0f, 0.0f, 0.1f, 0.8f, 0.2f,
5009 1.0f, -1.0f, 0.1f, 0.8f, 0.2f,
5010 1.0f, 0.0f, 0.1f, 0.8f, 0.2f,
5012 D3DMATRIX mat =
5014 0.0f, 0.0f, 0.0f, 0.0f,
5015 0.0f, 0.0f, 0.0f, 0.0f,
5016 0.0f, 1.0f, 0.0f, 0.0f,
5017 0.0f, 0.0f, 0.0f, 0.0f,
5018 }}};
5020 /* What happens to the default 1 in the 3rd coordinate if it is disabled? */
5021 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5022 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5023 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
5024 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5026 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
5027 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
5029 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
5030 * it behaves like COUNT2 because normal textures require 2 coords. */
5031 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
5032 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5033 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
5034 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
5036 /* Just to be sure, the same as quad2 above */
5037 memset(&mat, 0, sizeof(mat));
5038 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5039 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5040 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
5041 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5042 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
5043 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
5045 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
5046 * used? And what happens to the first? */
5047 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
5048 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5049 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
5050 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
5052 hr = IDirect3DDevice9_EndScene(device);
5053 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
5055 color = getPixelColor(device, 160, 360);
5056 ok(color_match(color, 0x00ff0000, 1), "quad 1 has color %08x, expected 0x00ff0000\n", color);
5057 color = getPixelColor(device, 160, 120);
5058 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
5059 color = getPixelColor(device, 480, 120);
5060 ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
5061 "quad 3 has color %08x, expected 0x00ff8000\n", color);
5062 color = getPixelColor(device, 480, 360);
5063 ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00ff0000, 1),
5064 "quad 4 has color %08x, expected 0x0033cc00\n", color);
5065 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5066 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5068 IDirect3DTexture9_Release(texture);
5070 /* Test projected textures, without any fancy matrices */
5071 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
5072 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5073 if (SUCCEEDED(hr))
5075 struct projected_textures_test_run projected_tests_1[4] =
5078 "D3DTTFF_COUNT4 | D3DTTFF_PROJECTED - bottom left",
5079 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED,
5080 decl3,
5081 FALSE, TRUE,
5082 {120, 300, 240, 390},
5085 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED - bottom right",
5086 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
5087 decl3,
5088 FALSE, TRUE,
5089 {400, 360, 480, 420},
5091 /* Try with some invalid values */
5093 "0xffffffff (draws like COUNT4 | PROJECTED) - top left",
5094 0xffffffff,
5095 decl3,
5096 FALSE, TRUE,
5097 {120, 60, 240, 150}
5100 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (draws non-projected) - top right",
5101 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
5102 decl4,
5103 FALSE, TRUE,
5104 {340, 210, 360, 225},
5107 struct projected_textures_test_run projected_tests_2[4] =
5110 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED, texcoord has 4 components) - bottom left",
5111 D3DTTFF_PROJECTED,
5112 decl3,
5113 FALSE, TRUE,
5114 {120, 300, 240, 390},
5117 "D3DTTFF_PROJECTED (like COUNT3 | PROJECTED, texcoord has only 3 components) - bottom right",
5118 D3DTTFF_PROJECTED,
5119 decl,
5120 FALSE, TRUE,
5121 {400, 360, 480, 420},
5124 "0xffffffff (like COUNT3 | PROJECTED, texcoord has only 3 components) - top left",
5125 0xffffffff,
5126 decl,
5127 FALSE, TRUE,
5128 {80, 120, 160, 180},
5131 "D3DTTFF_COUNT1 (draws non-projected) - top right",
5132 D3DTTFF_COUNT1,
5133 decl4,
5134 FALSE, TRUE,
5135 {340, 210, 360, 225},
5138 struct projected_textures_test_run projected_tests_3[4] =
5141 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom left",
5142 D3DTTFF_PROJECTED,
5143 decl3,
5144 TRUE, FALSE,
5145 {120, 300, 240, 390},
5148 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom right",
5149 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
5150 decl3,
5151 TRUE, TRUE,
5152 {440, 300, 560, 390},
5155 "0xffffffff (like COUNT4 | PROJECTED) - top left",
5156 0xffffffff,
5157 decl3,
5158 TRUE, TRUE,
5159 {120, 60, 240, 150},
5162 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - top right",
5163 D3DTTFF_PROJECTED,
5164 decl3,
5165 FALSE, FALSE,
5166 {440, 60, 560, 150},
5170 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
5171 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5173 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5174 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
5175 for(x = 0; x < 4; x++) {
5176 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
5178 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5179 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
5180 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5181 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
5183 projected_textures_test(device, projected_tests_1);
5184 projected_textures_test(device, projected_tests_2);
5185 projected_textures_test(device, projected_tests_3);
5187 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5188 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
5189 IDirect3DTexture9_Release(texture);
5192 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
5193 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5194 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
5195 * Thus watch out if sampling from texels between 0 and 1.
5197 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
5198 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
5199 "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
5200 if(!volume) {
5201 skip("Failed to create a volume texture\n");
5202 goto out;
5205 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
5206 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
5207 for(z = 0; z < 32; z++) {
5208 for(y = 0; y < 32; y++) {
5209 for(x = 0; x < 32; x++) {
5210 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
5211 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
5212 float r_f = (float) x / 31.0;
5213 float g_f = (float) y / 31.0;
5214 float b_f = (float) z / 31.0;
5216 if(fmt == D3DFMT_A16B16G16R16) {
5217 unsigned short *mem_s = mem;
5218 mem_s[0] = r_f * 65535.0;
5219 mem_s[1] = g_f * 65535.0;
5220 mem_s[2] = b_f * 65535.0;
5221 mem_s[3] = 65535;
5222 } else {
5223 unsigned char *mem_c = mem;
5224 mem_c[0] = b_f * 255.0;
5225 mem_c[1] = g_f * 255.0;
5226 mem_c[2] = r_f * 255.0;
5227 mem_c[3] = 255;
5232 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
5233 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
5235 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
5236 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
5238 hr = IDirect3DDevice9_BeginScene(device);
5239 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
5240 if(SUCCEEDED(hr))
5242 static const float quad1[] =
5244 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5245 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5246 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5247 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5249 static const float quad2[] =
5251 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5252 -1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5253 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5254 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5256 static const float quad3[] =
5258 0.0f, 0.0f, 0.1f, 0.0f, 0.0f,
5259 0.0f, 1.0f, 0.1f, 0.0f, 0.0f,
5260 1.0f, 0.0f, 0.1f, 0.0f, 0.0f,
5261 1.0f, 1.0f, 0.1f, 0.0f, 0.0f,
5263 static const float quad4[] =
5265 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5266 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5267 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5268 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5270 D3DMATRIX mat =
5272 1.0f, 0.0f, 0.0f, 0.0f,
5273 0.0f, 0.0f, 1.0f, 0.0f,
5274 0.0f, 1.0f, 0.0f, 0.0f,
5275 0.0f, 0.0f, 0.0f, 1.0f,
5276 }}};
5277 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5278 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5280 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
5281 * values
5283 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5284 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5285 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
5286 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5287 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5288 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5290 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
5291 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
5292 * otherwise the w will be missing(blue).
5293 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
5294 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3. */
5295 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
5296 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5297 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5298 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5300 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
5301 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
5302 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5303 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
5304 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5305 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5306 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5307 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
5308 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5310 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
5311 * disable. ATI extends it up to the amount of values needed for the volume texture
5313 memset(&mat, 0, sizeof(mat));
5314 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5315 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5316 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
5317 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5318 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5319 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5320 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5321 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5323 hr = IDirect3DDevice9_EndScene(device);
5324 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
5327 color = getPixelColor(device, 160, 360);
5328 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
5329 color = getPixelColor(device, 160, 120);
5330 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
5331 "quad 2 has color %08x, expected 0x00ffff00\n", color);
5332 color = getPixelColor(device, 480, 120);
5333 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
5334 color = getPixelColor(device, 480, 360);
5335 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
5337 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5338 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5340 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
5341 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5342 hr = IDirect3DDevice9_BeginScene(device);
5343 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
5344 if(SUCCEEDED(hr))
5346 static const float quad1[] =
5348 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5349 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5350 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5351 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5353 static const float quad2[] =
5355 -1.0f, 0.0f, 0.1f,
5356 -1.0f, 1.0f, 0.1f,
5357 0.0f, 0.0f, 0.1f,
5358 0.0f, 1.0f, 0.1f,
5360 static const float quad3[] =
5362 0.0f, 0.0f, 0.1f, 1.0f,
5363 0.0f, 1.0f, 0.1f, 1.0f,
5364 1.0f, 0.0f, 0.1f, 1.0f,
5365 1.0f, 1.0f, 0.1f, 1.0f,
5367 static const D3DMATRIX mat =
5369 0.0f, 0.0f, 0.0f, 0.0f,
5370 0.0f, 0.0f, 0.0f, 0.0f,
5371 0.0f, 0.0f, 0.0f, 0.0f,
5372 0.0f, 1.0f, 0.0f, 0.0f,
5373 }}};
5374 static const D3DMATRIX mat2 =
5376 0.0f, 0.0f, 0.0f, 1.0f,
5377 1.0f, 0.0f, 0.0f, 0.0f,
5378 0.0f, 1.0f, 0.0f, 0.0f,
5379 0.0f, 0.0f, 1.0f, 0.0f,
5380 }}};
5381 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5382 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5384 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
5385 * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
5386 * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
5387 * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
5388 * 4th *input* coordinate.
5390 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5391 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5392 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
5393 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5394 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5395 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5397 /* None passed */
5398 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
5399 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5400 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5401 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5402 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5403 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5405 /* 4 used, 1 passed */
5406 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5407 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5408 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat2);
5409 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5410 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
5411 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5413 hr = IDirect3DDevice9_EndScene(device);
5414 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
5416 color = getPixelColor(device, 160, 360);
5417 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
5418 color = getPixelColor(device, 160, 120);
5419 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
5420 color = getPixelColor(device, 480, 120);
5421 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
5422 /* Quad4: unused */
5424 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5425 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5427 IDirect3DVolumeTexture9_Release(volume);
5429 out:
5430 IDirect3DVertexDeclaration9_Release(decl);
5431 IDirect3DVertexDeclaration9_Release(decl2);
5432 IDirect3DVertexDeclaration9_Release(decl3);
5433 IDirect3DVertexDeclaration9_Release(decl4);
5434 refcount = IDirect3DDevice9_Release(device);
5435 ok(!refcount, "Device has %u references left.\n", refcount);
5436 done:
5437 IDirect3D9_Release(d3d);
5438 DestroyWindow(window);
5441 static void texdepth_test(void)
5443 IDirect3DPixelShader9 *shader;
5444 IDirect3DDevice9 *device;
5445 IDirect3D9 *d3d;
5446 ULONG refcount;
5447 D3DCAPS9 caps;
5448 DWORD color;
5449 HWND window;
5450 HRESULT hr;
5452 static const float texdepth_test_data1[] = { 0.25f, 2.0f, 0.0f, 0.0f};
5453 static const float texdepth_test_data2[] = { 0.25f, 0.5f, 0.0f, 0.0f};
5454 static const float texdepth_test_data3[] = {-1.00f, 0.1f, 0.0f, 0.0f};
5455 static const float texdepth_test_data4[] = {-0.25f, -0.5f, 0.0f, 0.0f};
5456 static const float texdepth_test_data5[] = { 1.00f, -0.1f, 0.0f, 0.0f};
5457 static const float texdepth_test_data6[] = { 1.00f, 0.5f, 0.0f, 0.0f};
5458 static const float texdepth_test_data7[] = { 0.50f, 0.0f, 0.0f, 0.0f};
5459 static const DWORD shader_code[] =
5461 0xffff0104, /* ps_1_4 */
5462 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
5463 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
5464 0x0000fffd, /* phase */
5465 0x00000057, 0x800f0005, /* texdepth r5 */
5466 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
5467 0x0000ffff /* end */
5469 static const float vertex[] =
5471 -1.0f, -1.0f, 0.0f,
5472 -1.0f, 1.0f, 0.0f,
5473 1.0f, -1.0f, 1.0f,
5474 1.0f, 1.0f, 1.0f,
5477 window = create_window();
5478 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5479 ok(!!d3d, "Failed to create a D3D object.\n");
5480 if (!(device = create_device(d3d, window, window, TRUE)))
5482 skip("Failed to create a D3D device, skipping tests.\n");
5483 goto done;
5486 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5487 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5488 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
5490 skip("No ps_1_4 support, skipping tests.\n");
5491 IDirect3DDevice9_Release(device);
5492 goto done;
5495 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5496 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5498 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
5499 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5500 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5501 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
5502 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
5503 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5504 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
5505 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5506 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
5507 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5508 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5509 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
5511 /* Fill the depth buffer with a gradient */
5512 hr = IDirect3DDevice9_BeginScene(device);
5513 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5514 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5515 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5516 hr = IDirect3DDevice9_EndScene(device);
5517 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5519 /* Now perform the actual tests. Same geometry, but with the shader */
5520 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
5521 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5522 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
5523 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5524 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5525 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5527 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
5528 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5529 hr = IDirect3DDevice9_BeginScene(device);
5530 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5531 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5532 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5533 hr = IDirect3DDevice9_EndScene(device);
5534 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5536 color = getPixelColor(device, 158, 240);
5537 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
5538 color = getPixelColor(device, 162, 240);
5539 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
5541 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5542 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5544 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5545 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5547 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
5548 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5549 hr = IDirect3DDevice9_BeginScene(device);
5550 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5551 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5552 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5553 hr = IDirect3DDevice9_EndScene(device);
5554 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5556 color = getPixelColor(device, 318, 240);
5557 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
5558 color = getPixelColor(device, 322, 240);
5559 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
5561 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5562 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5564 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
5565 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5567 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
5568 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5569 hr = IDirect3DDevice9_BeginScene(device);
5570 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5571 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5572 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5573 hr = IDirect3DDevice9_EndScene(device);
5574 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5576 color = getPixelColor(device, 1, 240);
5577 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
5579 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5580 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5582 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
5583 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5585 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
5586 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5587 hr = IDirect3DDevice9_BeginScene(device);
5588 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5589 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5590 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5591 hr = IDirect3DDevice9_EndScene(device);
5592 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5594 color = getPixelColor(device, 318, 240);
5595 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
5596 color = getPixelColor(device, 322, 240);
5597 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
5599 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5600 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5602 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5603 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5605 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
5606 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5607 hr = IDirect3DDevice9_BeginScene(device);
5608 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5609 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5610 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5611 hr = IDirect3DDevice9_EndScene(device);
5612 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5614 color = getPixelColor(device, 1, 240);
5615 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
5617 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5618 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5620 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
5621 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5623 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
5624 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5625 hr = IDirect3DDevice9_BeginScene(device);
5626 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5627 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5628 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5629 hr = IDirect3DDevice9_EndScene(device);
5630 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5632 color = getPixelColor(device, 638, 240);
5633 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
5635 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5636 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5638 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
5639 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5641 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
5642 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5643 hr = IDirect3DDevice9_BeginScene(device);
5644 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5645 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5646 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5647 hr = IDirect3DDevice9_EndScene(device);
5648 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5650 color = getPixelColor(device, 638, 240);
5651 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
5653 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5654 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5656 IDirect3DPixelShader9_Release(shader);
5657 refcount = IDirect3DDevice9_Release(device);
5658 ok(!refcount, "Device has %u references left.\n", refcount);
5659 done:
5660 IDirect3D9_Release(d3d);
5661 DestroyWindow(window);
5664 static void texkill_test(void)
5666 IDirect3DPixelShader9 *shader;
5667 IDirect3DDevice9 *device;
5668 IDirect3D9 *d3d;
5669 ULONG refcount;
5670 D3DCAPS9 caps;
5671 DWORD color;
5672 HWND window;
5673 HRESULT hr;
5675 static const float vertex[] =
5677 /* bottom top right left */
5678 -1.0f, -1.0f, 1.0f, -0.1f, 0.9f, 0.9f, -0.1f,
5679 -1.0f, 1.0f, 1.0f, -0.1f, 0.9f, -0.1f, 0.9f,
5680 1.0f, -1.0f, 0.0f, 0.9f, -0.1f, 0.9f, -0.1f,
5681 1.0f, 1.0f, 0.0f, 0.9f, -0.1f, -0.1f, 0.9f,
5683 static const DWORD shader_code_11[] =
5685 0xffff0101, /* ps_1_1 */
5686 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
5687 0x00000041, 0xb00f0000, /* texkill t0 */
5688 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5689 0x0000ffff /* end */
5691 static const DWORD shader_code_20[] =
5693 0xffff0200, /* ps_2_0 */
5694 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
5695 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
5696 0x01000041, 0xb00f0000, /* texkill t0 */
5697 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
5698 0x0000ffff /* end */
5701 window = create_window();
5702 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5703 ok(!!d3d, "Failed to create a D3D object.\n");
5704 if (!(device = create_device(d3d, window, window, TRUE)))
5706 skip("Failed to create a D3D device, skipping tests.\n");
5707 goto done;
5710 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5711 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5712 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
5714 skip("No ps_1_1 support, skipping tests.\n");
5715 IDirect3DDevice9_Release(device);
5716 goto done;
5719 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
5720 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5721 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
5722 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5724 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5725 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5726 hr = IDirect3DDevice9_BeginScene(device);
5727 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5728 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
5729 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5730 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
5731 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5732 hr = IDirect3DDevice9_EndScene(device);
5733 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5735 color = getPixelColor(device, 63, 46);
5736 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
5737 color = getPixelColor(device, 66, 46);
5738 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
5739 color = getPixelColor(device, 63, 49);
5740 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
5741 color = getPixelColor(device, 66, 49);
5742 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
5744 color = getPixelColor(device, 578, 46);
5745 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5746 color = getPixelColor(device, 575, 46);
5747 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5748 color = getPixelColor(device, 578, 49);
5749 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
5750 color = getPixelColor(device, 575, 49);
5751 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5753 color = getPixelColor(device, 63, 430);
5754 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5755 color = getPixelColor(device, 63, 433);
5756 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5757 color = getPixelColor(device, 66, 433);
5758 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
5759 color = getPixelColor(device, 66, 430);
5760 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5762 color = getPixelColor(device, 578, 430);
5763 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5764 color = getPixelColor(device, 578, 433);
5765 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5766 color = getPixelColor(device, 575, 433);
5767 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
5768 color = getPixelColor(device, 575, 430);
5769 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5771 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5772 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5774 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5775 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5776 IDirect3DPixelShader9_Release(shader);
5778 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5779 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5780 if (FAILED(IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader)))
5782 skip("Failed to create 2.0 test shader, most likely not supported.\n");
5783 IDirect3DDevice9_Release(device);
5784 goto done;
5787 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5788 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5789 hr = IDirect3DDevice9_BeginScene(device);
5790 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5791 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
5792 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5793 hr = IDirect3DDevice9_EndScene(device);
5794 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5796 color = getPixelColor(device, 63, 46);
5797 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
5798 color = getPixelColor(device, 66, 46);
5799 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
5800 color = getPixelColor(device, 63, 49);
5801 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
5802 color = getPixelColor(device, 66, 49);
5803 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
5805 color = getPixelColor(device, 578, 46);
5806 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5807 color = getPixelColor(device, 575, 46);
5808 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5809 color = getPixelColor(device, 578, 49);
5810 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5811 color = getPixelColor(device, 575, 49);
5812 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5814 color = getPixelColor(device, 63, 430);
5815 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5816 color = getPixelColor(device, 63, 433);
5817 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5818 color = getPixelColor(device, 66, 433);
5819 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5820 color = getPixelColor(device, 66, 430);
5821 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5823 color = getPixelColor(device, 578, 430);
5824 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5825 color = getPixelColor(device, 578, 433);
5826 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5827 color = getPixelColor(device, 575, 433);
5828 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5829 color = getPixelColor(device, 575, 430);
5830 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5832 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5833 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5835 IDirect3DPixelShader9_Release(shader);
5836 refcount = IDirect3DDevice9_Release(device);
5837 ok(!refcount, "Device has %u references left.\n", refcount);
5838 done:
5839 IDirect3D9_Release(d3d);
5840 DestroyWindow(window);
5843 static void autogen_mipmap_test(void)
5845 IDirect3DTexture9 *texture = NULL;
5846 IDirect3DSurface9 *surface;
5847 IDirect3DDevice9 *device;
5848 unsigned int x, y;
5849 D3DLOCKED_RECT lr;
5850 IDirect3D9 *d3d;
5851 D3DCOLOR color;
5852 ULONG refcount;
5853 HWND window;
5854 HRESULT hr;
5856 static const RECT r1 = {256, 256, 512, 512};
5857 static const RECT r2 = {512, 256, 768, 512};
5858 static const RECT r3 = {256, 512, 512, 768};
5859 static const RECT r4 = {512, 512, 768, 768};
5860 static const float quad[] =
5862 -0.5f, -0.5f, 0.1f, 0.0f, 0.0f,
5863 -0.5f, 0.5f, 0.1f, 0.0f, 1.0f,
5864 0.5f, -0.5f, 0.1f, 1.0f, 0.0f,
5865 0.5f, 0.5f, 0.1f, 1.0f, 1.0f,
5868 window = create_window();
5869 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5870 ok(!!d3d, "Failed to create a D3D object.\n");
5871 if (!(device = create_device(d3d, window, window, TRUE)))
5873 skip("Failed to create a D3D device, skipping tests.\n");
5874 goto done;
5877 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
5878 D3DFMT_X8R8G8B8, D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK)
5880 skip("No autogenmipmap support.\n");
5881 IDirect3DDevice9_Release(device);
5882 goto done;
5885 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 1.0f, 0);
5886 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5888 /* Make the mipmap big, so that a smaller mipmap is used
5890 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
5891 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
5892 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5894 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5895 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
5896 memset(&lr, 0, sizeof(lr));
5897 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5898 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
5899 for(y = 0; y < 1024; y++) {
5900 for(x = 0; x < 1024; x++) {
5901 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
5902 POINT pt;
5904 pt.x = x;
5905 pt.y = y;
5906 if(PtInRect(&r1, pt)) {
5907 *dst = 0xffff0000;
5908 } else if(PtInRect(&r2, pt)) {
5909 *dst = 0xff00ff00;
5910 } else if(PtInRect(&r3, pt)) {
5911 *dst = 0xff0000ff;
5912 } else if(PtInRect(&r4, pt)) {
5913 *dst = 0xff000000;
5914 } else {
5915 *dst = 0xffffffff;
5919 hr = IDirect3DSurface9_UnlockRect(surface);
5920 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
5921 IDirect3DSurface9_Release(surface);
5923 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5924 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5925 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
5926 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
5927 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5928 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
5930 hr = IDirect3DDevice9_BeginScene(device);
5931 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5932 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5933 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5934 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5935 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5936 hr = IDirect3DDevice9_EndScene(device);
5937 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5938 IDirect3DTexture9_Release(texture);
5940 color = getPixelColor(device, 200, 200);
5941 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
5942 color = getPixelColor(device, 280, 200);
5943 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
5944 color = getPixelColor(device, 360, 200);
5945 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
5946 color = getPixelColor(device, 440, 200);
5947 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5948 color = getPixelColor(device, 200, 270);
5949 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
5950 color = getPixelColor(device, 280, 270);
5951 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
5952 color = getPixelColor(device, 360, 270);
5953 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
5954 color = getPixelColor(device, 440, 270);
5955 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5956 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5957 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5959 refcount = IDirect3DDevice9_Release(device);
5960 ok(!refcount, "Device has %u references left.\n", refcount);
5961 done:
5962 IDirect3D9_Release(d3d);
5963 DestroyWindow(window);
5966 static void test_constant_clamp_vs(void)
5968 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
5969 IDirect3DVertexDeclaration9 *decl;
5970 IDirect3DDevice9 *device;
5971 IDirect3D9 *d3d;
5972 D3DCOLOR color;
5973 ULONG refcount;
5974 D3DCAPS9 caps;
5975 HWND window;
5976 HRESULT hr;
5978 static const DWORD shader_code_11[] =
5980 0xfffe0101, /* vs_1_1 */
5981 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5982 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5983 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5984 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5985 0x0000ffff /* end */
5987 static const DWORD shader_code_11_2[] =
5989 0xfffe0101, /* vs_1_1 */
5990 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
5991 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
5992 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5993 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5994 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5995 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5996 0x0000ffff /* end */
5998 static const DWORD shader_code_20[] =
6000 0xfffe0200, /* vs_2_0 */
6001 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6002 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6003 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
6004 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6005 0x0000ffff /* end */
6007 static const DWORD shader_code_20_2[] =
6009 0xfffe0200, /* vs_2_0 */
6010 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
6011 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
6012 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6013 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6014 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
6015 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6016 0x0000ffff /* end */
6018 static const D3DVERTEXELEMENT9 decl_elements[] =
6020 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6021 D3DDECL_END()
6023 static const float quad1[] =
6025 -1.0f, -1.0f, 0.1f,
6026 -1.0f, 0.0f, 0.1f,
6027 0.0f, -1.0f, 0.1f,
6028 0.0f, 0.0f, 0.1f,
6030 static const float quad2[] =
6032 0.0f, -1.0f, 0.1f,
6033 0.0f, 0.0f, 0.1f,
6034 1.0f, -1.0f, 0.1f,
6035 1.0f, 0.0f, 0.1f,
6037 static const float quad3[] =
6039 0.0f, 0.0f, 0.1f,
6040 0.0f, 1.0f, 0.1f,
6041 1.0f, 0.0f, 0.1f,
6042 1.0f, 1.0f, 0.1f,
6044 static const float quad4[] =
6046 -1.0f, 0.0f, 0.1f,
6047 -1.0f, 1.0f, 0.1f,
6048 0.0f, 0.0f, 0.1f,
6049 0.0f, 1.0f, 0.1f,
6051 static const float test_data_c1[4] = { 1.25f, -0.50f, -1.50f, 1.0f};
6052 static const float test_data_c2[4] = {-0.50f, 1.25f, 2.00f, 1.0f};
6054 window = create_window();
6055 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6056 ok(!!d3d, "Failed to create a D3D object.\n");
6057 if (!(device = create_device(d3d, window, window, TRUE)))
6059 skip("Failed to create a D3D device, skipping tests.\n");
6060 goto done;
6063 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6064 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6065 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
6067 skip("No vs_1_1 support, skipping tests.\n");
6068 IDirect3DDevice9_Release(device);
6069 goto done;
6072 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
6073 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6075 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
6076 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6077 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
6078 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6079 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
6080 if(FAILED(hr)) shader_20 = NULL;
6081 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
6082 if(FAILED(hr)) shader_20_2 = NULL;
6083 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
6084 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6086 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
6087 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
6088 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
6089 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
6090 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6091 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6093 hr = IDirect3DDevice9_BeginScene(device);
6094 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6096 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
6097 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
6098 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
6099 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6101 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
6102 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
6103 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
6104 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6106 if (shader_20)
6108 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
6109 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
6110 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
6111 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6114 if (shader_20_2)
6116 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
6117 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
6118 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
6119 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6122 hr = IDirect3DDevice9_EndScene(device);
6123 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6125 color = getPixelColor(device, 160, 360);
6126 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6127 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
6128 color = getPixelColor(device, 480, 360);
6129 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6130 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
6131 if(shader_20) {
6132 color = getPixelColor(device, 480, 120);
6133 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6134 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
6136 if(shader_20_2) {
6137 color = getPixelColor(device, 160, 120);
6138 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6139 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
6141 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6142 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6144 IDirect3DVertexDeclaration9_Release(decl);
6145 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
6146 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
6147 IDirect3DVertexShader9_Release(shader_11_2);
6148 IDirect3DVertexShader9_Release(shader_11);
6149 refcount = IDirect3DDevice9_Release(device);
6150 ok(!refcount, "Device has %u references left.\n", refcount);
6151 done:
6152 IDirect3D9_Release(d3d);
6153 DestroyWindow(window);
6156 static void constant_clamp_ps_test(void)
6158 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
6159 IDirect3DDevice9 *device;
6160 IDirect3D9 *d3d;
6161 ULONG refcount;
6162 D3DCAPS9 caps;
6163 DWORD color;
6164 HWND window;
6165 HRESULT hr;
6167 static const DWORD shader_code_11[] =
6169 0xffff0101, /* ps_1_1 */
6170 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6171 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6172 0x0000ffff /* end */
6174 static const DWORD shader_code_12[] =
6176 0xffff0102, /* ps_1_2 */
6177 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6178 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6179 0x0000ffff /* end */
6181 /* Skip 1.3 shaders because we have only 4 quads (ok, could make them
6182 * smaller if needed). 1.2 and 1.4 shaders behave the same, so it's
6183 * unlikely that 1.3 shaders are different. During development of this
6184 * test, 1.3 shaders were verified too. */
6185 static const DWORD shader_code_14[] =
6187 0xffff0104, /* ps_1_4 */
6188 /* Try to make one constant local. It gets clamped too, although the
6189 * binary contains the bigger numbers. */
6190 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
6191 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6192 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6193 0x0000ffff /* end */
6195 static const DWORD shader_code_20[] =
6197 0xffff0200, /* ps_2_0 */
6198 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6199 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6200 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6201 0x0000ffff /* end */
6203 static const float quad1[] =
6205 -1.0f, -1.0f, 0.1f,
6206 -1.0f, 0.0f, 0.1f,
6207 0.0f, -1.0f, 0.1f,
6208 0.0f, 0.0f, 0.1f,
6210 static const float quad2[] =
6212 0.0f, -1.0f, 0.1f,
6213 0.0f, 0.0f, 0.1f,
6214 1.0f, -1.0f, 0.1f,
6215 1.0f, 0.0f, 0.1f,
6217 static const float quad3[] =
6219 0.0f, 0.0f, 0.1f,
6220 0.0f, 1.0f, 0.1f,
6221 1.0f, 0.0f, 0.1f,
6222 1.0f, 1.0f, 0.1f,
6224 static const float quad4[] =
6226 -1.0f, 0.0f, 0.1f,
6227 -1.0f, 1.0f, 0.1f,
6228 0.0f, 0.0f, 0.1f,
6229 0.0f, 1.0f, 0.1f,
6231 static const float test_data_c1[4] = { 1.25f, -0.50f, -1.50f, 1.0f};
6232 static const float test_data_c2[4] = {-0.50f, 1.25f, 2.00f, 1.0f};
6234 window = create_window();
6235 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6236 ok(!!d3d, "Failed to create a D3D object.\n");
6237 if (!(device = create_device(d3d, window, window, TRUE)))
6239 skip("Failed to create a D3D device, skipping tests.\n");
6240 goto done;
6243 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6244 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6245 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
6247 skip("No ps_1_4 support, skipping tests.\n");
6248 IDirect3DDevice9_Release(device);
6249 goto done;
6252 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
6253 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6255 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
6256 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6257 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
6258 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6259 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
6260 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6261 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
6262 if(FAILED(hr)) shader_20 = NULL;
6264 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
6265 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6266 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
6267 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6268 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6269 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6271 hr = IDirect3DDevice9_BeginScene(device);
6272 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6274 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
6275 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6276 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
6277 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6279 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
6280 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6281 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
6282 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6284 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
6285 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6286 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
6287 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6289 if (shader_20)
6291 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
6292 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6293 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
6294 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6297 hr = IDirect3DDevice9_EndScene(device);
6298 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6300 color = getPixelColor(device, 160, 360);
6301 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
6302 "quad 1 has color %08x, expected 0x00808000\n", color);
6303 color = getPixelColor(device, 480, 360);
6304 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
6305 "quad 2 has color %08x, expected 0x00808000\n", color);
6306 color = getPixelColor(device, 480, 120);
6307 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
6308 "quad 3 has color %08x, expected 0x00808000\n", color);
6309 if(shader_20) {
6310 color = getPixelColor(device, 160, 120);
6311 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6312 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
6314 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6315 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6317 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
6318 IDirect3DPixelShader9_Release(shader_14);
6319 IDirect3DPixelShader9_Release(shader_12);
6320 IDirect3DPixelShader9_Release(shader_11);
6321 refcount = IDirect3DDevice9_Release(device);
6322 ok(!refcount, "Device has %u references left.\n", refcount);
6323 done:
6324 IDirect3D9_Release(d3d);
6325 DestroyWindow(window);
6328 static void dp2add_ps_test(void)
6330 IDirect3DPixelShader9 *shader_dp2add_sat;
6331 IDirect3DPixelShader9 *shader_dp2add;
6332 IDirect3DDevice9 *device;
6333 IDirect3D9 *d3d;
6334 ULONG refcount;
6335 D3DCAPS9 caps;
6336 DWORD color;
6337 HWND window;
6338 HRESULT hr;
6340 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
6341 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
6342 * source tokens can be constants. So, for this exercise, we move contents of c0 to
6343 * r0 first.
6344 * The result here for the r,g,b components should be roughly 0.5:
6345 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
6346 static const DWORD shader_code_dp2add[] = {
6347 0xffff0200, /* ps_2_0 */
6348 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
6350 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6351 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
6353 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
6354 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6355 0x0000ffff /* end */
6358 /* Test the _sat modifier, too. Result here should be:
6359 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
6360 * _SAT: ==> 1.0
6361 * ADD: (1.0 + -0.5) = 0.5
6363 static const DWORD shader_code_dp2add_sat[] = {
6364 0xffff0200, /* ps_2_0 */
6365 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
6367 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6368 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
6369 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
6371 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
6372 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6373 0x0000ffff /* end */
6375 static const float quad[] =
6377 -1.0f, -1.0f, 0.1f,
6378 -1.0f, 1.0f, 0.1f,
6379 1.0f, -1.0f, 0.1f,
6380 1.0f, 1.0f, 0.1f,
6383 window = create_window();
6384 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6385 ok(!!d3d, "Failed to create a D3D object.\n");
6386 if (!(device = create_device(d3d, window, window, TRUE)))
6388 skip("Failed to create a D3D device, skipping tests.\n");
6389 goto done;
6392 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6393 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6394 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
6396 skip("No ps_2_0 support, skipping tests.\n");
6397 IDirect3DDevice9_Release(device);
6398 goto done;
6401 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
6402 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6404 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
6405 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6407 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
6408 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6410 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6411 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6413 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
6414 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
6415 hr = IDirect3DDevice9_BeginScene(device);
6416 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6417 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
6418 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
6419 hr = IDirect3DDevice9_EndScene(device);
6420 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6422 color = getPixelColor(device, 360, 240);
6423 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1), "Got unexpected color 0x%08x.\n", color);
6425 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6426 ok(SUCCEEDED(hr), "Failed to present frame, hr %#x.\n", hr);
6427 IDirect3DPixelShader9_Release(shader_dp2add);
6429 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
6430 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
6431 hr = IDirect3DDevice9_BeginScene(device);
6432 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6433 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
6434 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
6435 hr = IDirect3DDevice9_EndScene(device);
6436 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6438 color = getPixelColor(device, 360, 240);
6439 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1), "Got unexpected color 0x%08x.\n", color);
6441 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6442 ok(SUCCEEDED(hr), "Failed to present frame, hr %#x.\n", hr);
6443 IDirect3DPixelShader9_Release(shader_dp2add_sat);
6445 refcount = IDirect3DDevice9_Release(device);
6446 ok(!refcount, "Device has %u references left.\n", refcount);
6447 done:
6448 IDirect3D9_Release(d3d);
6449 DestroyWindow(window);
6452 static void cnd_test(void)
6454 IDirect3DPixelShader9 *shader_11_coissue_2, *shader_12_coissue_2, *shader_13_coissue_2, *shader_14_coissue_2;
6455 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
6456 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
6457 IDirect3DDevice9 *device;
6458 IDirect3D9 *d3d;
6459 ULONG refcount;
6460 D3DCAPS9 caps;
6461 HWND window;
6462 DWORD color;
6463 HRESULT hr;
6465 /* ps 1.x shaders are rather picky with writemasks and source swizzles.
6466 * The dp3 is used to copy r0.r to all components of r1, then copy r1.a to
6467 * r0.a. Essentially it does a mov r0.a, r0.r, which isn't allowed as-is
6468 * in 1.x pixel shaders. */
6469 static const DWORD shader_code_11[] =
6471 0xffff0101, /* ps_1_1 */
6472 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6473 0x00000040, 0xb00f0000, /* texcoord t0 */
6474 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
6475 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
6476 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6477 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
6478 0x0000ffff /* end */
6480 static const DWORD shader_code_12[] =
6482 0xffff0102, /* ps_1_2 */
6483 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6484 0x00000040, 0xb00f0000, /* texcoord t0 */
6485 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6486 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
6487 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6488 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
6489 0x0000ffff /* end */
6491 static const DWORD shader_code_13[] =
6493 0xffff0103, /* ps_1_3 */
6494 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6495 0x00000040, 0xb00f0000, /* texcoord t0 */
6496 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6497 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
6498 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6499 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
6500 0x0000ffff /* end */
6502 static const DWORD shader_code_14[] =
6504 0xffff0104, /* ps_1_3 */
6505 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6506 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
6507 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
6508 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
6509 0x0000ffff /* end */
6512 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
6513 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
6514 * set by the compiler, it was added manually after compilation. Note that the COISSUE
6515 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
6516 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
6517 * well enough.
6519 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
6520 * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
6521 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
6522 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
6524 static const DWORD shader_code_11_coissue[] =
6526 0xffff0101, /* ps_1_1 */
6527 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6528 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6529 0x00000040, 0xb00f0000, /* texcoord t0 */
6530 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6531 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6532 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6533 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6534 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6535 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6536 0x0000ffff /* end */
6538 static const DWORD shader_code_11_coissue_2[] =
6540 0xffff0101, /* ps_1_1 */
6541 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6542 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6543 0x00000040, 0xb00f0000, /* texcoord t0 */
6544 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6545 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6546 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6547 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6548 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6549 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6550 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6551 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6552 0x0000ffff /* end */
6554 static const DWORD shader_code_12_coissue[] =
6556 0xffff0102, /* ps_1_2 */
6557 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6558 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6559 0x00000040, 0xb00f0000, /* texcoord t0 */
6560 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6561 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6562 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6563 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6564 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6565 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6566 0x0000ffff /* end */
6568 static const DWORD shader_code_12_coissue_2[] =
6570 0xffff0102, /* ps_1_2 */
6571 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6572 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6573 0x00000040, 0xb00f0000, /* texcoord t0 */
6574 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6575 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6576 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6577 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6578 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6579 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6580 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6581 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6582 0x0000ffff /* end */
6584 static const DWORD shader_code_13_coissue[] =
6586 0xffff0103, /* ps_1_3 */
6587 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6588 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6589 0x00000040, 0xb00f0000, /* texcoord t0 */
6590 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6591 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6592 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6593 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6594 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6595 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6596 0x0000ffff /* end */
6598 static const DWORD shader_code_13_coissue_2[] =
6600 0xffff0103, /* ps_1_3 */
6601 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6602 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6603 0x00000040, 0xb00f0000, /* texcoord t0 */
6604 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6605 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6606 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6607 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6608 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6609 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6610 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6611 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6612 0x0000ffff /* end */
6614 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1]
6615 * texcrd result to cnd, it will compare against 0.5. */
6616 static const DWORD shader_code_14_coissue[] =
6618 0xffff0104, /* ps_1_4 */
6619 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6620 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
6621 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
6622 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0, c1, c2 */
6623 0x0000ffff /* end */
6625 static const DWORD shader_code_14_coissue_2[] =
6627 0xffff0104, /* ps_1_4 */
6628 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6629 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
6630 0x00000001, 0x80080000, 0x80000000, /* mov r0.a, r0.x */
6631 0x00000001, 0x80070001, 0xa0ff0000, /* mov r1.xyz, c0.a */
6632 0x40000050, 0x80080001, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r1.a, r0.a, c1, c2 */
6633 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6634 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
6635 0x0000ffff /* end */
6637 static const float quad1[] =
6639 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6640 -1.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6641 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6642 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6644 static const float quad2[] =
6646 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6647 0.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6648 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6649 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6651 static const float quad3[] =
6653 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6654 0.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6655 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6656 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6658 static const float quad4[] =
6660 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6661 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6662 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6663 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6665 static const float test_data_c1[4] = {0.0f, 0.0f, 0.0f, 0.0f};
6666 static const float test_data_c2[4] = {1.0f, 1.0f, 1.0f, 1.0f};
6667 static const float test_data_c1_coi[4] = {0.0f, 1.0f, 0.0f, 0.0f};
6668 static const float test_data_c2_coi[4] = {1.0f, 0.0f, 1.0f, 1.0f};
6670 window = create_window();
6671 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6672 ok(!!d3d, "Failed to create a D3D object.\n");
6673 if (!(device = create_device(d3d, window, window, TRUE)))
6675 skip("Failed to create a D3D device, skipping tests.\n");
6676 goto done;
6679 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6680 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6681 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
6683 skip("No ps_1_4 support, skipping tests.\n");
6684 IDirect3DDevice9_Release(device);
6685 goto done;
6688 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
6689 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6691 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
6692 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6693 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
6694 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6695 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
6696 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6697 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
6698 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6699 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
6700 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6701 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
6702 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6703 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
6704 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6705 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
6706 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6707 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue_2, &shader_11_coissue_2);
6708 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6709 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue_2, &shader_12_coissue_2);
6710 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6711 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue_2, &shader_13_coissue_2);
6712 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6713 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue_2, &shader_14_coissue_2);
6714 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6716 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
6717 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6718 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
6719 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6720 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6721 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6723 hr = IDirect3DDevice9_BeginScene(device);
6724 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6726 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
6727 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6728 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6729 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6731 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
6732 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6733 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
6734 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6736 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
6737 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6738 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
6739 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6741 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
6742 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6743 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
6744 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6746 hr = IDirect3DDevice9_EndScene(device);
6747 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6749 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6750 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6752 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
6753 color = getPixelColor(device, 158, 118);
6754 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
6755 color = getPixelColor(device, 162, 118);
6756 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
6757 color = getPixelColor(device, 158, 122);
6758 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
6759 color = getPixelColor(device, 162, 122);
6760 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
6762 /* 1.1 shader. All 3 components get set, based on the .w comparison */
6763 color = getPixelColor(device, 158, 358);
6764 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
6765 color = getPixelColor(device, 162, 358);
6766 ok(color_match(color, 0x00000000, 1), "pixel 162, 358 has color 0x%08x, expected 0x00000000.\n", color);
6767 color = getPixelColor(device, 158, 362);
6768 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
6769 color = getPixelColor(device, 162, 362);
6770 ok(color_match(color, 0x00000000, 1), "pixel 162, 362 has color 0x%08x, expected 0x00000000.\n", color);
6772 /* 1.2 shader */
6773 color = getPixelColor(device, 478, 358);
6774 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
6775 color = getPixelColor(device, 482, 358);
6776 ok(color_match(color, 0x00000000, 1), "pixel 482, 358 has color 0x%08x, expected 0x00000000.\n", color);
6777 color = getPixelColor(device, 478, 362);
6778 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
6779 color = getPixelColor(device, 482, 362);
6780 ok(color_match(color, 0x00000000, 1), "pixel 482, 362 has color 0x%08x, expected 0x00000000.\n", color);
6782 /* 1.3 shader */
6783 color = getPixelColor(device, 478, 118);
6784 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
6785 color = getPixelColor(device, 482, 118);
6786 ok(color_match(color, 0x00000000, 1), "pixel 482, 118 has color 0x%08x, expected 0x00000000.\n", color);
6787 color = getPixelColor(device, 478, 122);
6788 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
6789 color = getPixelColor(device, 482, 122);
6790 ok(color_match(color, 0x00000000, 1), "pixel 482, 122 has color 0x%08x, expected 0x00000000.\n", color);
6792 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6793 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6795 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
6796 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6797 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
6798 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6799 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
6800 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6802 hr = IDirect3DDevice9_BeginScene(device);
6803 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6805 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
6806 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6807 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6808 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6810 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
6811 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6812 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
6813 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6815 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
6816 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6817 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
6818 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6820 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
6821 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6822 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
6823 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6825 hr = IDirect3DDevice9_EndScene(device);
6826 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6828 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6829 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6831 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
6832 * that we swapped the values in c1 and c2 to make the other tests return some color
6834 color = getPixelColor(device, 158, 118);
6835 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
6836 color = getPixelColor(device, 162, 118);
6837 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
6838 color = getPixelColor(device, 158, 122);
6839 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
6840 color = getPixelColor(device, 162, 122);
6841 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
6843 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
6844 * (The Win7 nvidia driver always selects c2)
6846 color = getPixelColor(device, 158, 358);
6847 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6848 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
6849 color = getPixelColor(device, 162, 358);
6850 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6851 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
6852 color = getPixelColor(device, 158, 362);
6853 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6854 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
6855 color = getPixelColor(device, 162, 362);
6856 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6857 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
6859 /* 1.2 shader */
6860 color = getPixelColor(device, 478, 358);
6861 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6862 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
6863 color = getPixelColor(device, 482, 358);
6864 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6865 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
6866 color = getPixelColor(device, 478, 362);
6867 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6868 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
6869 color = getPixelColor(device, 482, 362);
6870 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6871 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
6873 /* 1.3 shader */
6874 color = getPixelColor(device, 478, 118);
6875 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6876 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
6877 color = getPixelColor(device, 482, 118);
6878 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6879 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
6880 color = getPixelColor(device, 478, 122);
6881 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6882 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
6883 color = getPixelColor(device, 482, 122);
6884 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6885 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
6887 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6888 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6890 /* Retest with the coissue flag on the alpha instruction instead. This
6891 * works "as expected". The Windows 8 testbot (WARP) seems to handle this
6892 * the same as coissue on .rgb. */
6893 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
6894 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6896 hr = IDirect3DDevice9_BeginScene(device);
6897 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6899 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue_2);
6900 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6901 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6902 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6904 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue_2);
6905 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6906 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
6907 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6909 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue_2);
6910 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6911 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
6912 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6914 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue_2);
6915 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6916 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
6917 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6919 hr = IDirect3DDevice9_EndScene(device);
6920 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6922 /* 1.4 shader */
6923 color = getPixelColor(device, 158, 118);
6924 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
6925 color = getPixelColor(device, 162, 118);
6926 ok(color == 0x00000000, "pixel 162, 118 has color %08x, expected 0x00000000\n", color);
6927 color = getPixelColor(device, 158, 122);
6928 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
6929 color = getPixelColor(device, 162, 122);
6930 ok(color == 0x00000000, "pixel 162, 122 has color %08x, expected 0x00000000\n", color);
6932 /* 1.1 shader */
6933 color = getPixelColor(device, 238, 358);
6934 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6935 "pixel 238, 358 has color %08x, expected 0x00ffffff\n", color);
6936 color = getPixelColor(device, 242, 358);
6937 ok(color_match(color, 0x00000000, 1),
6938 "pixel 242, 358 has color %08x, expected 0x00000000\n", color);
6939 color = getPixelColor(device, 238, 362);
6940 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6941 "pixel 238, 362 has color %08x, expected 0x00ffffff\n", color);
6942 color = getPixelColor(device, 242, 362);
6943 ok(color_match(color, 0x00000000, 1),
6944 "pixel 242, 362 has color %08x, expected 0x00000000\n", color);
6946 /* 1.2 shader */
6947 color = getPixelColor(device, 558, 358);
6948 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6949 "pixel 558, 358 has color %08x, expected 0x00ffffff\n", color);
6950 color = getPixelColor(device, 562, 358);
6951 ok(color_match(color, 0x00000000, 1),
6952 "pixel 562, 358 has color %08x, expected 0x00000000\n", color);
6953 color = getPixelColor(device, 558, 362);
6954 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6955 "pixel 558, 362 has color %08x, expected 0x00ffffff\n", color);
6956 color = getPixelColor(device, 562, 362);
6957 ok(color_match(color, 0x00000000, 1),
6958 "pixel 562, 362 has color %08x, expected 0x00000000\n", color);
6960 /* 1.3 shader */
6961 color = getPixelColor(device, 558, 118);
6962 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6963 "pixel 558, 118 has color %08x, expected 0x00ffffff\n", color);
6964 color = getPixelColor(device, 562, 118);
6965 ok(color_match(color, 0x00000000, 1),
6966 "pixel 562, 118 has color %08x, expected 0x00000000\n", color);
6967 color = getPixelColor(device, 558, 122);
6968 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6969 "pixel 558, 122 has color %08x, expected 0x00ffffff\n", color);
6970 color = getPixelColor(device, 562, 122);
6971 ok(color_match(color, 0x00000000, 1),
6972 "pixel 562, 122 has color %08x, expected 0x00000000\n", color);
6974 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6975 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6977 IDirect3DPixelShader9_Release(shader_14_coissue_2);
6978 IDirect3DPixelShader9_Release(shader_13_coissue_2);
6979 IDirect3DPixelShader9_Release(shader_12_coissue_2);
6980 IDirect3DPixelShader9_Release(shader_11_coissue_2);
6981 IDirect3DPixelShader9_Release(shader_14_coissue);
6982 IDirect3DPixelShader9_Release(shader_13_coissue);
6983 IDirect3DPixelShader9_Release(shader_12_coissue);
6984 IDirect3DPixelShader9_Release(shader_11_coissue);
6985 IDirect3DPixelShader9_Release(shader_14);
6986 IDirect3DPixelShader9_Release(shader_13);
6987 IDirect3DPixelShader9_Release(shader_12);
6988 IDirect3DPixelShader9_Release(shader_11);
6989 refcount = IDirect3DDevice9_Release(device);
6990 ok(!refcount, "Device has %u references left.\n", refcount);
6991 done:
6992 IDirect3D9_Release(d3d);
6993 DestroyWindow(window);
6996 static void nested_loop_test(void)
6998 IDirect3DVertexShader9 *vshader;
6999 IDirect3DPixelShader9 *shader;
7000 IDirect3DDevice9 *device;
7001 IDirect3D9 *d3d;
7002 ULONG refcount;
7003 D3DCAPS9 caps;
7004 DWORD color;
7005 HWND window;
7006 HRESULT hr;
7008 static const DWORD shader_code[] =
7010 0xffff0300, /* ps_3_0 */
7011 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
7012 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
7013 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
7014 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7015 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
7016 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
7017 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
7018 0x0000001d, /* endloop */
7019 0x0000001d, /* endloop */
7020 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7021 0x0000ffff /* end */
7023 static const DWORD vshader_code[] =
7025 0xfffe0300, /* vs_3_0 */
7026 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7027 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7028 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7029 0x0000ffff /* end */
7031 static const float quad[] =
7033 -1.0f, -1.0f, 0.1f,
7034 -1.0f, 1.0f, 0.1f,
7035 1.0f, -1.0f, 0.1f,
7036 1.0f, 1.0f, 0.1f,
7039 window = create_window();
7040 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7041 ok(!!d3d, "Failed to create a D3D object.\n");
7042 if (!(device = create_device(d3d, window, window, TRUE)))
7044 skip("Failed to create a D3D device, skipping tests.\n");
7045 goto done;
7048 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7049 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7050 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
7052 skip("No shader model 3 support, skipping tests.\n");
7053 IDirect3DDevice9_Release(device);
7054 goto done;
7057 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7058 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
7059 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7060 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
7061 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
7062 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
7063 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
7064 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
7065 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7066 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
7067 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 1.0f, 0);
7068 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7070 hr = IDirect3DDevice9_BeginScene(device);
7071 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7072 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
7073 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7074 hr = IDirect3DDevice9_EndScene(device);
7075 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7077 color = getPixelColor(device, 360, 240);
7078 ok(color_match(color, 0x00800000, 1),
7079 "Nested loop test returned color 0x%08x, expected 0x00800000.\n", color);
7081 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7082 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7084 IDirect3DPixelShader9_Release(shader);
7085 IDirect3DVertexShader9_Release(vshader);
7086 refcount = IDirect3DDevice9_Release(device);
7087 ok(!refcount, "Device has %u references left.\n", refcount);
7088 done:
7089 IDirect3D9_Release(d3d);
7090 DestroyWindow(window);
7093 static void pretransformed_varying_test(void)
7095 /* dcl_position: fails to compile */
7096 static const DWORD blendweight_code[] =
7098 0xffff0300, /* ps_3_0 */
7099 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
7100 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7101 0x0000ffff /* end */
7103 static const DWORD blendindices_code[] =
7105 0xffff0300, /* ps_3_0 */
7106 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
7107 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7108 0x0000ffff /* end */
7110 static const DWORD normal_code[] =
7112 0xffff0300, /* ps_3_0 */
7113 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
7114 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7115 0x0000ffff /* end */
7117 /* psize: fails? */
7118 static const DWORD texcoord0_code[] =
7120 0xffff0300, /* ps_3_0 */
7121 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
7122 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7123 0x0000ffff /* end */
7125 static const DWORD tangent_code[] =
7127 0xffff0300, /* ps_3_0 */
7128 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
7129 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7130 0x0000ffff /* end */
7132 static const DWORD binormal_code[] =
7134 0xffff0300, /* ps_3_0 */
7135 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
7136 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7137 0x0000ffff /* end */
7139 /* tessfactor: fails */
7140 /* positiont: fails */
7141 static const DWORD color_code[] =
7143 0xffff0300, /* ps_3_0 */
7144 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
7145 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7146 0x0000ffff /* end */
7148 static const DWORD fog_code[] =
7150 0xffff0300, /* ps_3_0 */
7151 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
7152 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7153 0x0000ffff /* end */
7155 static const DWORD depth_code[] =
7157 0xffff0300, /* ps_3_0 */
7158 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
7159 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7160 0x0000ffff /* end */
7162 static const DWORD specular_code[] =
7164 0xffff0300, /* ps_3_0 */
7165 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
7166 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7167 0x0000ffff /* end */
7169 /* sample: fails */
7170 static const DWORD texcoord1_code[] =
7172 0xffff0300, /* ps_3_0 */
7173 0x0200001f, 0x80010005, 0x900f0000, /* dcl_texcoord1, v0 */
7174 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7175 0x0000ffff /* end */
7177 static const DWORD texcoord1_alpha_code[] =
7179 0xffff0300, /* ps_3_0 */
7180 0x0200001f, 0x80010005, 0x900f0000, /* dcl_texcoord1, v0 */
7181 0x02000001, 0x800f0800, 0x90ff0000, /* mov oC0, v0.w */
7182 0x0000ffff /* end */
7185 static const struct
7187 const char *name;
7188 const DWORD *shader_code;
7189 DWORD color;
7190 BOOL todo;
7191 BOOL broken_warp;
7193 tests[] =
7195 {"blendweight", blendweight_code, 0x00191919, TRUE },
7196 {"blendindices", blendindices_code, 0x00333333, TRUE },
7197 {"normal", normal_code, 0x004c4c4c, TRUE },
7198 {"texcoord0", texcoord0_code, 0x00808c8c, FALSE},
7199 {"tangent", tangent_code, 0x00999999, TRUE },
7200 {"binormal", binormal_code, 0x00b2b2b2, TRUE },
7201 {"color", color_code, 0x00e6e6e6, FALSE},
7202 {"fog", fog_code, 0x00666666, TRUE },
7203 {"depth", depth_code, 0x00cccccc, TRUE },
7204 {"specular", specular_code, 0x004488ff, FALSE},
7205 {"texcoord1", texcoord1_code, 0x00000000, FALSE},
7206 {"texcoord1 alpha", texcoord1_alpha_code, 0x00000000, FALSE, TRUE},
7208 /* Declare a monster vertex type :-) */
7209 static const D3DVERTEXELEMENT9 decl_elements[] = {
7210 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
7211 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
7212 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
7213 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
7214 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
7215 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7216 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
7217 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
7218 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
7219 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7220 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
7221 D3DDECL_END()
7224 static const struct
7226 float pos_x, pos_y, pos_z, rhw;
7227 float weight_1, weight_2, weight_3, weight_4;
7228 float index_1, index_2, index_3, index_4;
7229 float normal_1, normal_2, normal_3, normal_4;
7230 float fog_1, fog_2, fog_3, fog_4;
7231 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
7232 float tangent_1, tangent_2, tangent_3, tangent_4;
7233 float binormal_1, binormal_2, binormal_3, binormal_4;
7234 float depth_1, depth_2, depth_3, depth_4;
7235 D3DCOLOR diffuse;
7236 D3DCOLOR specular;
7238 data[] =
7241 0.0f, 0.0f, 0.1f, 1.0f,
7242 0.1f, 0.1f, 0.1f, 0.1f,
7243 0.2f, 0.2f, 0.2f, 0.2f,
7244 0.3f, 0.3f, 0.3f, 0.3f,
7245 0.4f, 0.4f, 0.4f, 0.4f,
7246 0.5f, 0.55f, 0.55f, 0.55f,
7247 0.6f, 0.6f, 0.6f, 0.7f,
7248 0.7f, 0.7f, 0.7f, 0.6f,
7249 0.8f, 0.8f, 0.8f, 0.8f,
7250 0xe6e6e6e6, /* 0.9 * 256 */
7251 0x224488ff, /* Nothing special */
7254 640.0f, 0.0f, 0.1f, 1.0f,
7255 0.1f, 0.1f, 0.1f, 0.1f,
7256 0.2f, 0.2f, 0.2f, 0.2f,
7257 0.3f, 0.3f, 0.3f, 0.3f,
7258 0.4f, 0.4f, 0.4f, 0.4f,
7259 0.5f, 0.55f, 0.55f, 0.55f,
7260 0.6f, 0.6f, 0.6f, 0.7f,
7261 0.7f, 0.7f, 0.7f, 0.6f,
7262 0.8f, 0.8f, 0.8f, 0.8f,
7263 0xe6e6e6e6, /* 0.9 * 256 */
7264 0x224488ff, /* Nothing special */
7267 0.0f, 480.0f, 0.1f, 1.0f,
7268 0.1f, 0.1f, 0.1f, 0.1f,
7269 0.2f, 0.2f, 0.2f, 0.2f,
7270 0.3f, 0.3f, 0.3f, 0.3f,
7271 0.4f, 0.4f, 0.4f, 0.4f,
7272 0.5f, 0.55f, 0.55f, 0.55f,
7273 0.6f, 0.6f, 0.6f, 0.7f,
7274 0.7f, 0.7f, 0.7f, 0.6f,
7275 0.8f, 0.8f, 0.8f, 0.8f,
7276 0xe6e6e6e6, /* 0.9 * 256 */
7277 0x224488ff, /* Nothing special */
7280 640.0f, 480.0f, 0.1f, 1.0f,
7281 0.1f, 0.1f, 0.1f, 0.1f,
7282 0.2f, 0.2f, 0.2f, 0.2f,
7283 0.3f, 0.3f, 0.3f, 0.3f,
7284 0.4f, 0.4f, 0.4f, 0.4f,
7285 0.5f, 0.55f, 0.55f, 0.55f,
7286 0.6f, 0.6f, 0.6f, 0.7f,
7287 0.7f, 0.7f, 0.7f, 0.6f,
7288 0.8f, 0.8f, 0.8f, 0.8f,
7289 0xe6e6e6e6, /* 0.9 * 256 */
7290 0x224488ff, /* Nothing special */
7293 D3DADAPTER_IDENTIFIER9 identifier;
7294 IDirect3DVertexDeclaration9 *decl;
7295 IDirect3DDevice9 *device;
7296 IDirect3D9 *d3d;
7297 unsigned int i;
7298 ULONG refcount;
7299 D3DCAPS9 caps;
7300 DWORD color;
7301 HWND window;
7302 HRESULT hr;
7303 BOOL warp;
7305 window = create_window();
7306 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7307 ok(!!d3d, "Failed to create a D3D object.\n");
7308 if (!(device = create_device(d3d, window, window, TRUE)))
7310 skip("Failed to create a D3D device, skipping tests.\n");
7311 goto done;
7314 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7315 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7316 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
7318 skip("No shader model 3 support, skipping tests.\n");
7319 IDirect3DDevice9_Release(device);
7320 goto done;
7323 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
7324 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
7325 warp = adapter_is_warp(&identifier);
7327 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
7328 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7329 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
7330 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
7332 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
7334 IDirect3DPixelShader9 *shader;
7336 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
7337 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7339 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &shader);
7340 ok(SUCCEEDED(hr), "Failed to create pixel shader for test %s, hr %#x.\n", tests[i].name, hr);
7342 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7343 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7345 hr = IDirect3DDevice9_BeginScene(device);
7346 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7347 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(*data));
7348 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7349 hr = IDirect3DDevice9_EndScene(device);
7350 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7352 /* This isn't a weekend's job to fix, ignore the problem for now.
7353 * Needs a replacement pipeline. */
7354 color = getPixelColor(device, 360, 240);
7355 if (tests[i].todo)
7356 todo_wine ok(color_match(color, tests[i].color, 1)
7357 || broken(color_match(color, 0x00000000, 1)
7358 && tests[i].shader_code == blendindices_code),
7359 "Test %s returned color 0x%08x, expected 0x%08x (todo).\n",
7360 tests[i].name, color, tests[i].color);
7361 else
7362 ok(color_match(color, tests[i].color, 1) || broken(warp && tests[i].broken_warp),
7363 "Test %s returned color 0x%08x, expected 0x%08x.\n",
7364 tests[i].name, color, tests[i].color);
7366 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7367 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7369 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7370 ok(SUCCEEDED(hr), "Failed to set pixel shader for test %s, hr %#x.\n", tests[i].name, hr);
7371 IDirect3DPixelShader9_Release(shader);
7374 IDirect3DVertexDeclaration9_Release(decl);
7375 refcount = IDirect3DDevice9_Release(device);
7376 ok(!refcount, "Device has %u references left.\n", refcount);
7377 done:
7378 IDirect3D9_Release(d3d);
7379 DestroyWindow(window);
7382 static void test_compare_instructions(void)
7384 IDirect3DVertexShader9 *shader_slt_scalar;
7385 IDirect3DVertexShader9 *shader_sge_scalar;
7386 IDirect3DVertexShader9 *shader_slt_vec;
7387 IDirect3DVertexShader9 *shader_sge_vec;
7388 IDirect3DDevice9 *device;
7389 IDirect3D9 *d3d;
7390 D3DCOLOR color;
7391 ULONG refcount;
7392 D3DCAPS9 caps;
7393 HWND window;
7394 HRESULT hr;
7396 static const DWORD shader_sge_vec_code[] =
7398 0xfffe0101, /* vs_1_1 */
7399 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7400 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7401 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7402 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
7403 0x0000ffff /* end */
7405 static const DWORD shader_slt_vec_code[] =
7407 0xfffe0101, /* vs_1_1 */
7408 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7409 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7410 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7411 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
7412 0x0000ffff /* end */
7414 static const DWORD shader_sge_scalar_code[] =
7416 0xfffe0101, /* vs_1_1 */
7417 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7418 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7419 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7420 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
7421 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
7422 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
7423 0x0000ffff /* end */
7425 static const DWORD shader_slt_scalar_code[] =
7427 0xfffe0101, /* vs_1_1 */
7428 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7429 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7430 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7431 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
7432 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
7433 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
7434 0x0000ffff /* end */
7436 static const float quad1[] =
7438 -1.0f, -1.0f, 0.1f,
7439 -1.0f, 0.0f, 0.1f,
7440 0.0f, -1.0f, 0.1f,
7441 0.0f, 0.0f, 0.1f,
7443 static const float quad2[] =
7445 0.0f, -1.0f, 0.1f,
7446 0.0f, 0.0f, 0.1f,
7447 1.0f, -1.0f, 0.1f,
7448 1.0f, 0.0f, 0.1f,
7450 static const float quad3[] =
7452 -1.0f, 0.0f, 0.1f,
7453 -1.0f, 1.0f, 0.1f,
7454 0.0f, 0.0f, 0.1f,
7455 0.0f, 1.0f, 0.1f,
7457 static const float quad4[] =
7459 0.0f, 0.0f, 0.1f,
7460 0.0f, 1.0f, 0.1f,
7461 1.0f, 0.0f, 0.1f,
7462 1.0f, 1.0f, 0.1f,
7464 static const float const0[4] = {0.8f, 0.2f, 0.2f, 0.2f};
7465 static const float const1[4] = {0.2f, 0.8f, 0.2f, 0.2f};
7467 window = create_window();
7468 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7469 ok(!!d3d, "Failed to create a D3D object.\n");
7470 if (!(device = create_device(d3d, window, window, TRUE)))
7472 skip("Failed to create a D3D device, skipping tests.\n");
7473 goto done;
7476 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7477 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7478 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
7480 skip("No vs_1_1 support, skipping tests.\n");
7481 IDirect3DDevice9_Release(device);
7482 goto done;
7485 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
7486 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
7488 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
7489 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7490 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
7491 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7492 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
7493 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7494 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
7495 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7496 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
7497 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
7498 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
7499 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
7500 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7501 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
7503 hr = IDirect3DDevice9_BeginScene(device);
7504 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7506 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
7507 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7508 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
7509 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7511 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
7512 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7513 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
7514 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7516 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
7517 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7518 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
7519 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7521 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
7522 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
7524 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
7525 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7526 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
7527 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7529 hr = IDirect3DDevice9_EndScene(device);
7530 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7532 color = getPixelColor(device, 160, 360);
7533 ok(color == 0x00ff00ff, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00ff00ff\n", color);
7534 color = getPixelColor(device, 480, 360);
7535 ok(color == 0x0000ff00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000ff00\n", color);
7536 color = getPixelColor(device, 160, 120);
7537 ok(color == 0x00ffffff, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00ffffff\n", color);
7538 color = getPixelColor(device, 480, 160);
7539 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
7541 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7542 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7544 IDirect3DVertexShader9_Release(shader_sge_vec);
7545 IDirect3DVertexShader9_Release(shader_slt_vec);
7546 IDirect3DVertexShader9_Release(shader_sge_scalar);
7547 IDirect3DVertexShader9_Release(shader_slt_scalar);
7548 refcount = IDirect3DDevice9_Release(device);
7549 ok(!refcount, "Device has %u references left.\n", refcount);
7550 done:
7551 IDirect3D9_Release(d3d);
7552 DestroyWindow(window);
7555 static void test_vshader_input(void)
7557 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
7558 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
7559 IDirect3DVertexDeclaration9 *decl_nocolor;
7560 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
7561 D3DADAPTER_IDENTIFIER9 identifier;
7562 IDirect3DPixelShader9 *ps;
7563 IDirect3DDevice9 *device;
7564 IDirect3D9 *d3d;
7565 ULONG refcount;
7566 unsigned int i;
7567 D3DCAPS9 caps;
7568 DWORD color;
7569 HWND window;
7570 HRESULT hr;
7571 BOOL warp;
7573 static const DWORD swapped_shader_code_3[] =
7575 0xfffe0300, /* vs_3_0 */
7576 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7577 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7578 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7579 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7580 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7581 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7582 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7583 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7584 0x0000ffff /* end */
7586 static const DWORD swapped_shader_code_1[] =
7588 0xfffe0101, /* vs_1_1 */
7589 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7590 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7591 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7592 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
7593 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7594 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7595 0x0000ffff /* end */
7597 static const DWORD swapped_shader_code_2[] =
7599 0xfffe0200, /* vs_2_0 */
7600 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7601 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7602 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7603 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
7604 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7605 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7606 0x0000ffff /* end */
7608 static const DWORD texcoord_color_shader_code_3[] =
7610 0xfffe0300, /* vs_3_0 */
7611 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7612 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7613 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7614 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7615 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7616 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
7617 0x0000ffff /* end */
7619 static const DWORD texcoord_color_shader_code_2[] =
7621 0xfffe0200, /* vs_2_0 */
7622 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7623 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7624 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7625 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
7626 0x0000ffff /* end */
7628 static const DWORD texcoord_color_shader_code_1[] =
7630 0xfffe0101, /* vs_1_1 */
7631 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7632 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7633 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7634 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
7635 0x0000ffff /* end */
7637 static const DWORD color_color_shader_code_3[] =
7639 0xfffe0300, /* vs_3_0 */
7640 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7641 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7642 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7643 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7644 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7645 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
7646 0x0000ffff /* end */
7648 static const DWORD color_color_shader_code_2[] =
7650 0xfffe0200, /* vs_2_0 */
7651 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7652 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7653 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7654 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
7655 0x0000ffff /* end */
7657 static const DWORD color_color_shader_code_1[] =
7659 0xfffe0101, /* vs_1_1 */
7660 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7661 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7662 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7663 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
7664 0x0000ffff /* end */
7666 static const DWORD ps3_code[] =
7668 0xffff0300, /* ps_3_0 */
7669 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
7670 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7671 0x0000ffff /* end */
7673 static const float quad1[] =
7675 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7676 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7677 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7678 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7680 static const float quad2[] =
7682 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7683 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7684 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7685 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7687 static const float quad3[] =
7689 -1.0f, 0.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f,
7690 -1.0f, 1.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
7691 0.0f, 0.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
7692 0.0f, 1.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
7694 static const float quad4[] =
7696 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7697 0.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7698 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7699 1.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7701 static const float quad1_modified[] =
7703 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
7704 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f,
7705 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
7706 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, -1.0f, -1.0f, 0.0f,
7708 static const float quad2_modified[] =
7710 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7711 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7712 1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7713 1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7715 static const struct
7717 struct vec3 position;
7718 DWORD diffuse;
7720 quad1_color[] =
7722 {{-1.0f, -1.0f, 0.1f}, 0x00ff8040},
7723 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
7724 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7725 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7727 quad2_color[] =
7729 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7730 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7731 {{ 1.0f, -1.0f, 0.1f}, 0x00ff8040},
7732 {{ 1.0f, 0.0f, 0.1f}, 0x00ff8040},
7734 quad3_color[] =
7736 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
7737 {{-1.0f, 1.0f, 0.1f}, 0x00ff8040},
7738 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7739 {{ 0.0f, 1.0f, 0.1f}, 0x00ff8040},
7741 static const float quad4_color[] =
7743 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7744 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7745 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7746 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7748 static const struct vec3 quad_nocolor[] =
7750 {-1.0f, -1.0f, 0.1f},
7751 {-1.0f, 1.0f, 0.1f},
7752 { 1.0f, -1.0f, 0.1f},
7753 { 1.0f, 1.0f, 0.1f},
7755 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] =
7757 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7758 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7759 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7760 D3DDECL_END()
7762 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] =
7764 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7765 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7766 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7767 D3DDECL_END()
7769 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] =
7771 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7772 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7773 D3DDECL_END()
7775 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] =
7777 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7778 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7779 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
7780 D3DDECL_END()
7782 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] =
7784 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7785 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7786 D3DDECL_END()
7788 static const D3DVERTEXELEMENT9 decl_elements_color_color[] =
7790 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7791 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7792 D3DDECL_END()
7794 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] =
7796 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7797 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7798 D3DDECL_END()
7800 static const D3DVERTEXELEMENT9 decl_elements_color_float[] =
7802 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7803 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7804 D3DDECL_END()
7806 static const D3DVERTEXELEMENT9 decl_elements_nocolor[] =
7808 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7809 D3DDECL_END()
7811 static const float normalize[4] = {1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f};
7812 static const float no_normalize[4] = {1.0f, 1.0f, 1.0f, 1.0f};
7814 window = create_window();
7815 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7816 ok(!!d3d, "Failed to create a D3D object.\n");
7817 if (!(device = create_device(d3d, window, window, TRUE)))
7819 skip("Failed to create a D3D device, skipping tests.\n");
7820 goto done;
7823 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7824 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7825 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
7827 skip("No vs_3_0 support, skipping tests.\n");
7828 IDirect3DDevice9_Release(device);
7829 goto done;
7831 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
7833 skip("No ps_3_0 support, skipping tests.\n");
7834 IDirect3DDevice9_Release(device);
7835 goto done;
7838 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
7839 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
7840 warp = adapter_is_warp(&identifier);
7842 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
7843 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7844 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
7845 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7846 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
7847 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7848 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
7849 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7851 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
7852 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7853 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
7854 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7855 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
7856 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7857 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
7858 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7859 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_nocolor, &decl_nocolor);
7860 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7862 hr = IDirect3DDevice9_CreatePixelShader(device, ps3_code, &ps);
7863 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
7865 for (i = 1; i <= 3; ++i)
7867 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
7868 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
7869 if(i == 3) {
7870 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
7871 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7872 hr = IDirect3DDevice9_SetPixelShader(device, ps);
7873 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7874 } else if(i == 2){
7875 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
7876 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7877 } else if(i == 1) {
7878 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
7879 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7882 hr = IDirect3DDevice9_BeginScene(device);
7883 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7885 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
7886 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7888 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
7889 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7890 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
7891 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7893 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
7894 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7895 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
7896 if (i == 3 || i == 2)
7897 ok(SUCCEEDED(hr), "Failed to draw, i %u, hr %#x.\n", i, hr);
7898 else if (i == 1)
7899 /* Succeeds or fails, depending on SW or HW vertex processing. */
7900 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
7902 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
7903 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7904 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
7905 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7907 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
7908 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7909 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
7910 if (i == 3 || i == 2)
7911 ok(SUCCEEDED(hr), "Failed to draw, i %u, hr %#x.\n", i, hr);
7912 else if (i == 1)
7913 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
7915 hr = IDirect3DDevice9_EndScene(device);
7916 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7918 if(i == 3 || i == 2) {
7919 color = getPixelColor(device, 160, 360);
7920 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
7921 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00ffff80\n", color);
7923 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
7924 color = getPixelColor(device, 480, 360);
7925 /* On the Windows 8 testbot (WARP) the draw succeeds, but uses
7926 * mostly random data as input. */
7927 ok(color == 0x00ffff00 || color == 0x00ff0000 || broken(warp),
7928 "Got unexpected color 0x%08x for quad 2 (1crd).\n", color);
7929 color = getPixelColor(device, 160, 120);
7930 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
7931 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
7932 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00ff0080\n", color);
7934 color = getPixelColor(device, 480, 160);
7935 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
7936 } else if(i == 1) {
7937 color = getPixelColor(device, 160, 360);
7938 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
7939 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00ffff80\n", color);
7940 color = getPixelColor(device, 480, 360);
7941 /* Accept the clear color as well in this case, since SW VP
7942 * returns an error. On the Windows 8 testbot (WARP) the draw
7943 * succeeds, but uses mostly random data as input. */
7944 ok(color == 0x00ffff00 || color == 0x00ff0000 || broken(warp),
7945 "Got unexpected color 0x%08x for quad 2 (1crd).\n", color);
7946 color = getPixelColor(device, 160, 120);
7947 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
7948 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00ff0080\n", color);
7949 color = getPixelColor(device, 480, 160);
7950 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
7953 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7954 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7956 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
7957 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7959 /* Now find out if the whole streams are re-read, or just the last
7960 * active value for the vertices is used. */
7961 hr = IDirect3DDevice9_BeginScene(device);
7962 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7964 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
7965 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7967 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
7968 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7969 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
7970 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7972 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
7973 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7974 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
7975 if (i == 3 || i == 2)
7976 ok(SUCCEEDED(hr), "Failed to draw, i %u, hr %#x.\n", i, hr);
7977 else if (i == 1)
7978 /* Succeeds or fails, depending on SW or HW vertex processing. */
7979 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
7981 hr = IDirect3DDevice9_EndScene(device);
7982 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7984 color = getPixelColor(device, 480, 350);
7985 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
7986 * as well.
7988 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
7989 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
7990 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
7991 * refrast's result.
7993 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
7995 ok(color == 0x000000ff || color == 0x00808080 || color == 0x00000000
7996 || broken(color_match(color, D3DCOLOR_ARGB(0x00, 0x0b, 0x75, 0x80), 1)),
7997 "Got unexpected color 0x%08x for quad 2 (different colors).\n", color);
7999 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8000 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8002 IDirect3DDevice9_SetVertexShader(device, NULL);
8003 IDirect3DDevice9_SetPixelShader(device, NULL);
8004 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8006 IDirect3DVertexShader9_Release(swapped_shader);
8009 for (i = 1; i <= 3; ++i)
8011 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
8012 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
8013 if(i == 3) {
8014 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
8015 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8016 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
8017 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8018 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8019 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
8020 } else if(i == 2){
8021 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
8022 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8023 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
8024 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8025 } else if(i == 1) {
8026 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
8027 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8028 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
8029 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8032 hr = IDirect3DDevice9_BeginScene(device);
8033 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8035 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
8036 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8037 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
8038 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8039 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
8040 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8042 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
8043 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8045 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
8046 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
8047 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
8048 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8049 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
8050 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8052 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
8053 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
8054 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
8055 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8056 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
8057 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8059 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
8060 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8061 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
8062 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8064 hr = IDirect3DDevice9_EndScene(device);
8065 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8067 color = getPixelColor(device, 160, 360);
8068 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
8069 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
8070 color = getPixelColor(device, 480, 360);
8071 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
8072 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
8073 color = getPixelColor(device, 160, 120);
8074 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
8075 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
8076 color = getPixelColor(device, 480, 160);
8077 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
8078 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00ffff00\n", color);
8080 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8081 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8083 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_nocolor);
8084 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8086 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
8087 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8089 hr = IDirect3DDevice9_BeginScene(device);
8090 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8091 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_nocolor, sizeof(quad_nocolor[0]));
8092 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8093 hr = IDirect3DDevice9_EndScene(device);
8094 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8096 color = getPixelColor(device, 160, 360);
8097 ok(color_match(color, 0x00000000, 1) || broken(warp),
8098 "Got unexpected color 0x%08x for no color attribute test.\n", color);
8100 IDirect3DDevice9_SetVertexShader(device, NULL);
8101 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8102 IDirect3DDevice9_SetPixelShader(device, NULL);
8104 IDirect3DVertexShader9_Release(texcoord_color_shader);
8105 IDirect3DVertexShader9_Release(color_color_shader);
8108 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
8109 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
8110 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
8111 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
8113 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
8114 IDirect3DVertexDeclaration9_Release(decl_color_color);
8115 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
8116 IDirect3DVertexDeclaration9_Release(decl_color_float);
8117 IDirect3DVertexDeclaration9_Release(decl_nocolor);
8119 IDirect3DPixelShader9_Release(ps);
8120 refcount = IDirect3DDevice9_Release(device);
8121 ok(!refcount, "Device has %u references left.\n", refcount);
8122 done:
8123 IDirect3D9_Release(d3d);
8124 DestroyWindow(window);
8127 static void srgbtexture_test(void)
8129 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
8130 * texture stage state to render a quad using that texture. The resulting
8131 * color components should be 0x36 (~ 0.21), per this formula:
8132 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
8133 * This is true where srgb_color > 0.04045. */
8134 struct IDirect3DTexture9 *texture;
8135 struct IDirect3DSurface9 *surface;
8136 IDirect3DDevice9 *device;
8137 IDirect3D9 *d3d;
8138 D3DCOLOR color;
8139 ULONG refcount;
8140 HWND window;
8141 HRESULT hr;
8143 static const float quad[] =
8145 -1.0f, -1.0f, 0.0f, 0.0f, 1.0f,
8146 -1.0f, 1.0f, 0.0f, 0.0f, 0.0f,
8147 1.0f, -1.0f, 0.0f, 1.0f, 1.0f,
8148 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
8151 window = create_window();
8152 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8153 ok(!!d3d, "Failed to create a D3D object.\n");
8154 if (!(device = create_device(d3d, window, window, TRUE)))
8156 skip("Failed to create a D3D device, skipping tests.\n");
8157 goto done;
8160 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
8161 D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK)
8163 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported.\n");
8164 IDirect3DDevice9_Release(device);
8165 goto done;
8168 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
8169 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
8170 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8171 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
8173 fill_surface(surface, 0xff7f7f7f, 0);
8174 IDirect3DSurface9_Release(surface);
8176 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8177 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8178 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8179 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
8181 hr = IDirect3DDevice9_BeginScene(device);
8182 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8184 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
8185 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
8186 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8187 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8188 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
8189 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8191 hr = IDirect3DDevice9_EndScene(device);
8192 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8194 color = getPixelColor(device, 320, 240);
8195 ok(color_match(color, 0x00363636, 1), "sRGB quad has color 0x%08x, expected 0x00363636.\n", color);
8197 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8198 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8200 IDirect3DTexture9_Release(texture);
8201 refcount = IDirect3DDevice9_Release(device);
8202 ok(!refcount, "Device has %u references left.\n", refcount);
8203 done:
8204 IDirect3D9_Release(d3d);
8205 DestroyWindow(window);
8208 static void test_shademode(void)
8210 IDirect3DVertexBuffer9 *vb_strip;
8211 IDirect3DVertexBuffer9 *vb_list;
8212 IDirect3DVertexShader9 *vs;
8213 IDirect3DPixelShader9 *ps;
8214 IDirect3DDevice9 *device;
8215 DWORD color0, color1;
8216 void *data = NULL;
8217 IDirect3D9 *d3d;
8218 ULONG refcount;
8219 D3DCAPS9 caps;
8220 HWND window;
8221 HRESULT hr;
8222 UINT i;
8223 static const DWORD vs1_code[] =
8225 0xfffe0101, /* vs_1_1 */
8226 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8227 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
8228 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8229 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
8230 0x0000ffff
8232 static const DWORD vs2_code[] =
8234 0xfffe0200, /* vs_2_0 */
8235 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8236 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
8237 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8238 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
8239 0x0000ffff
8241 static const DWORD vs3_code[] =
8243 0xfffe0300, /* vs_3_0 */
8244 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8245 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
8246 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8247 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
8248 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8249 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
8250 0x0000ffff
8252 static const DWORD ps1_code[] =
8254 0xffff0101, /* ps_1_1 */
8255 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
8256 0x0000ffff
8258 static const DWORD ps2_code[] =
8260 0xffff0200, /* ps_2_0 */
8261 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
8262 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8263 0x0000ffff
8265 static const DWORD ps3_code[] =
8267 0xffff0300, /* ps_3_0 */
8268 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
8269 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8270 0x0000ffff
8272 static const struct
8274 struct vec3 position;
8275 DWORD diffuse;
8277 quad_strip[] =
8279 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
8280 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8281 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8282 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
8284 quad_list[] =
8286 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
8287 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8288 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8290 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8291 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8292 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
8294 static const struct test_shader
8296 DWORD version;
8297 const DWORD *code;
8299 novs = {0, NULL},
8300 vs_1 = {D3DVS_VERSION(1, 1), vs1_code},
8301 vs_2 = {D3DVS_VERSION(2, 0), vs2_code},
8302 vs_3 = {D3DVS_VERSION(3, 0), vs3_code},
8303 nops = {0, NULL},
8304 ps_1 = {D3DPS_VERSION(1, 1), ps1_code},
8305 ps_2 = {D3DPS_VERSION(2, 0), ps2_code},
8306 ps_3 = {D3DPS_VERSION(3, 0), ps3_code};
8307 static const struct
8309 const struct test_shader *vs, *ps;
8310 DWORD primtype;
8311 DWORD shademode;
8312 DWORD color0, color1;
8313 BOOL todo;
8315 tests[] =
8317 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8318 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_PHONG, 0x000dca28, 0x000d45c7, FALSE},
8319 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8320 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_PHONG, 0x000dca28, 0x000d45c7, FALSE},
8321 {&novs, &nops, D3DPT_TRIANGLELIST, D3DSHADE_FLAT, 0x00ff0000, 0x000000ff, FALSE},
8322 {&novs, &nops, D3DPT_TRIANGLELIST, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8323 {&vs_1, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8324 {&vs_1, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8325 {&vs_1, &ps_1, D3DPT_TRIANGLELIST, D3DSHADE_FLAT, 0x00ff0000, 0x000000ff, FALSE},
8326 {&vs_1, &ps_1, D3DPT_TRIANGLELIST, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8327 {&novs, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8328 {&vs_1, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8329 {&vs_2, &ps_2, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8330 {&vs_2, &ps_2, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8331 {&vs_3, &ps_3, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, TRUE},
8332 {&vs_3, &ps_3, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8335 window = create_window();
8336 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8337 ok(!!d3d, "Failed to create a D3D object.\n");
8338 if (!(device = create_device(d3d, window, window, TRUE)))
8340 skip("Failed to create a D3D device, skipping tests.\n");
8341 goto done;
8344 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8345 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8346 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
8347 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
8349 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8350 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
8352 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip), 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
8353 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8354 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
8355 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8356 memcpy(data, quad_strip, sizeof(quad_strip));
8357 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
8358 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
8360 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list), 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
8361 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8362 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
8363 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8364 memcpy(data, quad_list, sizeof(quad_list));
8365 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
8366 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
8368 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8369 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
8371 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
8372 * the color fixups we have to do for FLAT shading will be dependent on that. */
8374 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
8376 if (tests[i].vs->version)
8378 if (caps.VertexShaderVersion >= tests[i].vs->version)
8380 hr = IDirect3DDevice9_CreateVertexShader(device, tests[i].vs->code, &vs);
8381 ok(hr == D3D_OK, "Failed to create vertex shader, hr %#x.\n", hr);
8382 hr = IDirect3DDevice9_SetVertexShader(device, vs);
8383 ok(hr == D3D_OK, "Failed to set vertex shader, hr %#x.\n", hr);
8385 else
8387 skip("Shader version unsupported, skipping some tests.\n");
8388 continue;
8391 else
8393 vs = NULL;
8395 if (tests[i].ps->version)
8397 if (caps.PixelShaderVersion >= tests[i].ps->version)
8399 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].ps->code, &ps);
8400 ok(hr == D3D_OK, "Failed to create pixel shader, hr %#x.\n", hr);
8401 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8402 ok(hr == D3D_OK, "Failed to set pixel shader, hr %#x.\n", hr);
8404 else
8406 skip("Shader version unsupported, skipping some tests.\n");
8407 if (vs)
8409 IDirect3DDevice9_SetVertexShader(device, NULL);
8410 IDirect3DVertexShader9_Release(vs);
8412 continue;
8415 else
8417 ps = NULL;
8420 hr = IDirect3DDevice9_SetStreamSource(device, 0,
8421 tests[i].primtype == D3DPT_TRIANGLESTRIP ? vb_strip : vb_list, 0, sizeof(quad_strip[0]));
8422 ok(hr == D3D_OK, "Failed to set stream source, hr %#x.\n", hr);
8424 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
8425 ok(hr == D3D_OK, "Failed to clear, hr %#x.\n", hr);
8427 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shademode);
8428 ok(hr == D3D_OK, "Failed to set shade mode, hr %#x.\n", hr);
8430 hr = IDirect3DDevice9_BeginScene(device);
8431 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8432 hr = IDirect3DDevice9_DrawPrimitive(device, tests[i].primtype, 0, 2);
8433 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8434 hr = IDirect3DDevice9_EndScene(device);
8435 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8437 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
8438 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
8440 /* For D3DSHADE_FLAT it should take the color of the first vertex of
8441 * each triangle. This requires EXT_provoking_vertex or similar
8442 * functionality being available. */
8443 /* PHONG should be the same as GOURAUD, since no hardware implements
8444 * this. */
8445 todo_wine_if (tests[i].todo)
8447 ok(color_match(color0, tests[i].color0, 1), "Test %u shading has color0 %08x, expected %08x.\n",
8448 i, color0, tests[i].color0);
8449 ok(color_match(color1, tests[i].color1, 1), "Test %u shading has color1 %08x, expected %08x.\n",
8450 i, color1, tests[i].color1);
8452 IDirect3DDevice9_SetVertexShader(device, NULL);
8453 IDirect3DDevice9_SetPixelShader(device, NULL);
8455 if (ps)
8456 IDirect3DPixelShader9_Release(ps);
8457 if (vs)
8458 IDirect3DVertexShader9_Release(vs);
8461 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8462 ok(hr == D3D_OK, "Failed to present, hr %#x.\n", hr);
8464 IDirect3DVertexBuffer9_Release(vb_strip);
8465 IDirect3DVertexBuffer9_Release(vb_list);
8466 refcount = IDirect3DDevice9_Release(device);
8467 ok(!refcount, "Device has %u references left.\n", refcount);
8468 done:
8469 IDirect3D9_Release(d3d);
8470 DestroyWindow(window);
8473 static void test_blend(void)
8475 IDirect3DSurface9 *backbuffer, *offscreen;
8476 IDirect3DTexture9 *offscreenTexture;
8477 IDirect3DDevice9 *device;
8478 IDirect3D9 *d3d;
8479 D3DCOLOR color;
8480 ULONG refcount;
8481 HWND window;
8482 HRESULT hr;
8484 static const struct
8486 struct vec3 position;
8487 DWORD diffuse;
8489 quad1[] =
8491 {{-1.0f, -1.0f, 0.1f}, 0x4000ff00},
8492 {{-1.0f, 0.0f, 0.1f}, 0x4000ff00},
8493 {{ 1.0f, -1.0f, 0.1f}, 0x4000ff00},
8494 {{ 1.0f, 0.0f, 0.1f}, 0x4000ff00},
8496 quad2[] =
8498 {{-1.0f, 0.0f, 0.1f}, 0xc00000ff},
8499 {{-1.0f, 1.0f, 0.1f}, 0xc00000ff},
8500 {{ 1.0f, 0.0f, 0.1f}, 0xc00000ff},
8501 {{ 1.0f, 1.0f, 0.1f}, 0xc00000ff},
8503 static const float composite_quad[][5] =
8505 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
8506 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
8507 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
8508 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
8511 window = create_window();
8512 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8513 ok(!!d3d, "Failed to create a D3D object.\n");
8514 if (!(device = create_device(d3d, window, window, TRUE)))
8516 skip("Failed to create a D3D device, skipping tests.\n");
8517 goto done;
8520 /* Clear the render target with alpha = 0.5 */
8521 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x80ff0000, 1.0f, 0);
8522 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8524 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
8525 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8526 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
8528 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8529 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8531 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8532 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8534 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8535 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
8537 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8538 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8539 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8540 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8541 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8542 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8543 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8544 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8545 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8546 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8548 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8549 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8550 hr = IDirect3DDevice9_BeginScene(device);
8551 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8553 /* Draw two quads, one with src alpha blending, one with dest alpha
8554 * blending. */
8555 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8556 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8557 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8558 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8559 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8560 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8562 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
8563 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8564 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
8565 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8566 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8567 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8569 /* Switch to the offscreen buffer, and redo the testing. The offscreen
8570 * render target doesn't have an alpha channel. DESTALPHA and INVDESTALPHA
8571 * "don't work" on render targets without alpha channel, they give
8572 * essentially ZERO and ONE blend factors. */
8573 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8574 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8575 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x80ff0000, 1.0f, 0);
8576 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8578 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8579 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8580 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8581 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8582 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8583 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8585 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
8586 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8587 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
8588 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8589 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8590 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8592 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8593 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8595 /* Render the offscreen texture onto the frame buffer to be able to
8596 * compare it regularly. Disable alpha blending for the final
8597 * composition. */
8598 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8599 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8600 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8601 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8603 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8604 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
8605 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
8606 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8608 hr = IDirect3DDevice9_EndScene(device);
8609 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8611 color = getPixelColor(device, 160, 360);
8612 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
8613 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
8615 color = getPixelColor(device, 160, 120);
8616 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
8617 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
8619 color = getPixelColor(device, 480, 360);
8620 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
8621 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
8623 color = getPixelColor(device, 480, 120);
8624 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
8625 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
8627 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8629 IDirect3DSurface9_Release(backbuffer);
8630 IDirect3DTexture9_Release(offscreenTexture);
8631 IDirect3DSurface9_Release(offscreen);
8632 refcount = IDirect3DDevice9_Release(device);
8633 ok(!refcount, "Device has %u references left.\n", refcount);
8634 done:
8635 IDirect3D9_Release(d3d);
8636 DestroyWindow(window);
8639 static void fixed_function_decl_test(void)
8641 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
8642 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_nocolor, *dcl_positiont;
8643 IDirect3DVertexBuffer9 *vb, *vb2;
8644 IDirect3DDevice9 *device;
8645 BOOL s_ok, ub_ok, f_ok;
8646 DWORD color, size, i;
8647 IDirect3D9 *d3d;
8648 ULONG refcount;
8649 D3DCAPS9 caps;
8650 HWND window;
8651 void *data;
8652 HRESULT hr;
8654 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
8655 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8656 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8657 D3DDECL_END()
8659 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
8660 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8661 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8662 D3DDECL_END()
8664 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
8665 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8666 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8667 D3DDECL_END()
8669 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
8670 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8671 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8672 D3DDECL_END()
8674 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
8675 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8676 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8677 D3DDECL_END()
8679 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
8680 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8681 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8682 D3DDECL_END()
8684 static const D3DVERTEXELEMENT9 decl_elements_nocolor[] = {
8685 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8686 D3DDECL_END()
8688 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
8689 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
8690 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8691 D3DDECL_END()
8693 static const struct
8695 struct vec3 position;
8696 DWORD diffuse;
8698 quad1[] = /* D3DCOLOR */
8700 {{-1.0f, -1.0f, 0.1f}, 0x00ffff00},
8701 {{-1.0f, 0.0f, 0.1f}, 0x00ffff00},
8702 {{ 0.0f, -1.0f, 0.1f}, 0x00ffff00},
8703 {{ 0.0f, 0.0f, 0.1f}, 0x00ffff00},
8705 quad2[] = /* UBYTE4N */
8707 {{-1.0f, 0.0f, 0.1f}, 0x00ffff00},
8708 {{-1.0f, 1.0f, 0.1f}, 0x00ffff00},
8709 {{ 0.0f, 0.0f, 0.1f}, 0x00ffff00},
8710 {{ 0.0f, 1.0f, 0.1f}, 0x00ffff00},
8712 static const struct
8714 struct vec3 position;
8715 struct { unsigned short x, y, z, w; } color;
8717 quad3[] = /* USHORT4N */
8719 {{0.0f, -1.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8720 {{0.0f, 0.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8721 {{1.0f, -1.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8722 {{1.0f, 0.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8724 static const struct
8726 struct vec3 position;
8727 struct vec4 color;
8729 quad4[] =
8731 {{0.0f, 0.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8732 {{0.0f, 1.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8733 {{1.0f, 0.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8734 {{1.0f, 1.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8736 static const DWORD colors[] =
8738 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8739 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8740 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8741 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8742 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8743 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8744 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8745 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8746 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8747 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8748 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8749 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8750 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8751 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8752 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8753 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8755 static const float quads[] =
8757 -1.0f, -1.0f, 0.1f,
8758 -1.0f, 0.0f, 0.1f,
8759 0.0f, -1.0f, 0.1f,
8760 0.0f, 0.0f, 0.1f,
8762 0.0f, -1.0f, 0.1f,
8763 0.0f, 0.0f, 0.1f,
8764 1.0f, -1.0f, 0.1f,
8765 1.0f, 0.0f, 0.1f,
8767 0.0f, 0.0f, 0.1f,
8768 0.0f, 1.0f, 0.1f,
8769 1.0f, 0.0f, 0.1f,
8770 1.0f, 1.0f, 0.1f,
8772 -1.0f, 0.0f, 0.1f,
8773 -1.0f, 1.0f, 0.1f,
8774 0.0f, 0.0f, 0.1f,
8775 0.0f, 1.0f, 0.1f,
8777 static const struct
8779 struct vec4 position;
8780 DWORD diffuse;
8782 quad_transformed[] =
8784 {{ 90.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
8785 {{570.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
8786 {{ 90.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
8787 {{570.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
8790 window = create_window();
8791 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8792 ok(!!d3d, "Failed to create a D3D object.\n");
8793 if (!(device = create_device(d3d, window, window, TRUE)))
8795 skip("Failed to create a D3D device, skipping tests.\n");
8796 goto done;
8799 memset(&caps, 0, sizeof(caps));
8800 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8801 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
8803 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
8804 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8806 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
8807 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8808 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
8809 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
8810 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
8811 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8812 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
8813 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
8814 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8815 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
8816 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8817 } else {
8818 trace("D3DDTCAPS_UBYTE4N not supported\n");
8819 dcl_ubyte_2 = NULL;
8820 dcl_ubyte = NULL;
8822 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
8823 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8824 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_nocolor, &dcl_nocolor);
8825 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8826 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
8827 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8829 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
8830 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
8831 0, 0, D3DPOOL_MANAGED, &vb, NULL);
8832 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8834 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8835 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
8837 hr = IDirect3DDevice9_BeginScene(device);
8838 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8840 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
8841 if (dcl_color)
8843 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
8844 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8845 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8846 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8849 /* Tests with non-standard fixed function types fail on the refrast. The
8850 * ATI driver partially accepts them, the NVIDIA driver accepts them all.
8851 * All those differences even though we're using software vertex
8852 * processing. Doh! */
8853 if (dcl_ubyte)
8855 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
8856 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8857 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8858 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8859 ub_ok = SUCCEEDED(hr);
8862 if (dcl_short)
8864 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
8865 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8866 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
8867 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8868 s_ok = SUCCEEDED(hr);
8871 if (dcl_float)
8873 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
8874 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8875 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
8876 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8877 f_ok = SUCCEEDED(hr);
8880 hr = IDirect3DDevice9_EndScene(device);
8881 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8883 if(dcl_short) {
8884 color = getPixelColor(device, 480, 360);
8885 ok(color == 0x000000ff || !s_ok,
8886 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
8888 if(dcl_ubyte) {
8889 color = getPixelColor(device, 160, 120);
8890 ok(color == 0x0000ffff || !ub_ok,
8891 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
8893 if(dcl_color) {
8894 color = getPixelColor(device, 160, 360);
8895 ok(color == 0x00ffff00,
8896 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
8898 if(dcl_float) {
8899 color = getPixelColor(device, 480, 120);
8900 ok(color == 0x00ff0000 || !f_ok,
8901 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
8903 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8905 /* The following test with vertex buffers doesn't serve to find out new
8906 * information from windows. It is a plain regression test because wined3d
8907 * uses different codepaths for attribute conversion with vertex buffers.
8908 * It makes sure that the vertex buffer one works, while the above tests
8909 * whether the immediate mode code works. */
8910 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
8911 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
8912 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8913 hr = IDirect3DDevice9_BeginScene(device);
8914 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8916 if (dcl_color)
8918 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
8919 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8920 memcpy(data, quad1, sizeof(quad1));
8921 hr = IDirect3DVertexBuffer9_Unlock(vb);
8922 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8923 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
8924 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8925 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
8926 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8927 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8928 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8931 if (dcl_ubyte)
8933 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
8934 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8935 memcpy(data, quad2, sizeof(quad2));
8936 hr = IDirect3DVertexBuffer9_Unlock(vb);
8937 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8938 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
8939 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8940 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
8941 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8942 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8943 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8944 ub_ok = SUCCEEDED(hr);
8947 if (dcl_short)
8949 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
8950 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8951 memcpy(data, quad3, sizeof(quad3));
8952 hr = IDirect3DVertexBuffer9_Unlock(vb);
8953 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8954 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
8955 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8956 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
8957 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8958 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8959 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8960 s_ok = SUCCEEDED(hr);
8963 if (dcl_float)
8965 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
8966 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8967 memcpy(data, quad4, sizeof(quad4));
8968 hr = IDirect3DVertexBuffer9_Unlock(vb);
8969 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8970 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
8971 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8972 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
8973 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8974 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8975 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8976 f_ok = SUCCEEDED(hr);
8979 hr = IDirect3DDevice9_EndScene(device);
8980 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8982 if(dcl_short) {
8983 color = getPixelColor(device, 480, 360);
8984 ok(color == 0x000000ff || !s_ok,
8985 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
8987 if(dcl_ubyte) {
8988 color = getPixelColor(device, 160, 120);
8989 ok(color == 0x0000ffff || !ub_ok,
8990 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
8992 if(dcl_color) {
8993 color = getPixelColor(device, 160, 360);
8994 ok(color == 0x00ffff00,
8995 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
8997 if(dcl_float) {
8998 color = getPixelColor(device, 480, 120);
8999 ok(color == 0x00ff0000 || !f_ok,
9000 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
9002 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9004 /* Test with no diffuse color attribute. */
9005 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9006 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9008 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_nocolor);
9009 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9010 hr = IDirect3DDevice9_BeginScene(device);
9011 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9012 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quads, sizeof(float) * 3);
9013 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9014 hr = IDirect3DDevice9_EndScene(device);
9015 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9017 color = getPixelColor(device, 160, 360);
9018 ok(color == 0x00ffffff, "Got unexpected color 0x%08x in the no color attribute test.\n", color);
9020 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9022 /* Test what happens with specular lighting enabled and no specular color attribute. */
9023 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
9024 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
9025 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9026 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
9027 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#x.\n", hr);
9028 hr = IDirect3DDevice9_BeginScene(device);
9029 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9031 if (dcl_color)
9033 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
9034 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9035 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9036 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9038 if (dcl_ubyte)
9040 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
9041 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9042 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9043 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9044 ub_ok = SUCCEEDED(hr);
9046 if (dcl_short)
9048 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
9049 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9050 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
9051 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9052 s_ok = SUCCEEDED(hr);
9054 if (dcl_float)
9056 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
9057 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9058 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
9059 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9060 f_ok = SUCCEEDED(hr);
9063 hr = IDirect3DDevice9_EndScene(device);
9064 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9065 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARENABLE, FALSE);
9066 ok(SUCCEEDED(hr), "Failed to disable specular lighting, hr %#x.\n", hr);
9068 if (dcl_short)
9070 color = getPixelColor(device, 480, 360);
9071 ok(color == 0x000000ff || !s_ok,
9072 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff.\n", color);
9074 if (dcl_ubyte)
9076 color = getPixelColor(device, 160, 120);
9077 ok(color == 0x0000ffff || !ub_ok,
9078 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff.\n", color);
9080 if (dcl_color)
9082 color = getPixelColor(device, 160, 360);
9083 ok(color == 0x00ffff00,
9084 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00.\n", color);
9086 if (dcl_float)
9088 color = getPixelColor(device, 480, 120);
9089 ok(color == 0x00ff0000 || !f_ok,
9090 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000.\n", color);
9092 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9094 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
9095 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9096 memcpy(data, quad_transformed, sizeof(quad_transformed));
9097 hr = IDirect3DVertexBuffer9_Unlock(vb);
9098 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
9100 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
9101 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
9103 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9104 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9106 hr = IDirect3DDevice9_BeginScene(device);
9107 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9108 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
9109 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
9110 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9111 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9112 hr = IDirect3DDevice9_EndScene(device);
9113 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9115 color = getPixelColor(device, 88, 108);
9116 ok(color == 0x000000ff,
9117 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
9118 color = getPixelColor(device, 92, 108);
9119 ok(color == 0x000000ff,
9120 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
9121 color = getPixelColor(device, 88, 112);
9122 ok(color == 0x000000ff,
9123 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
9124 color = getPixelColor(device, 92, 112);
9125 ok(color == 0x00ffff00,
9126 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
9128 color = getPixelColor(device, 568, 108);
9129 ok(color == 0x000000ff,
9130 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
9131 color = getPixelColor(device, 572, 108);
9132 ok(color == 0x000000ff,
9133 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
9134 color = getPixelColor(device, 568, 112);
9135 ok(color == 0x00ffff00,
9136 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
9137 color = getPixelColor(device, 572, 112);
9138 ok(color == 0x000000ff,
9139 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
9141 color = getPixelColor(device, 88, 298);
9142 ok(color == 0x000000ff,
9143 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
9144 color = getPixelColor(device, 92, 298);
9145 ok(color == 0x00ffff00,
9146 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
9147 color = getPixelColor(device, 88, 302);
9148 ok(color == 0x000000ff,
9149 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
9150 color = getPixelColor(device, 92, 302);
9151 ok(color == 0x000000ff,
9152 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
9154 color = getPixelColor(device, 568, 298);
9155 ok(color == 0x00ffff00,
9156 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
9157 color = getPixelColor(device, 572, 298);
9158 ok(color == 0x000000ff,
9159 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
9160 color = getPixelColor(device, 568, 302);
9161 ok(color == 0x000000ff,
9162 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
9163 color = getPixelColor(device, 572, 302);
9164 ok(color == 0x000000ff,
9165 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
9167 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9169 /* This test is pointless without those two declarations: */
9170 if((!dcl_color_2) || (!dcl_ubyte_2)) {
9171 skip("color-ubyte switching test declarations aren't supported\n");
9172 goto out;
9175 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
9176 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9177 memcpy(data, quads, sizeof(quads));
9178 hr = IDirect3DVertexBuffer9_Unlock(vb);
9179 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
9180 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
9181 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9182 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9183 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
9184 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9185 memcpy(data, colors, sizeof(colors));
9186 hr = IDirect3DVertexBuffer9_Unlock(vb2);
9187 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
9189 for(i = 0; i < 2; i++) {
9190 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9191 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9193 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
9194 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
9195 if(i == 0) {
9196 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
9197 } else {
9198 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
9200 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
9202 hr = IDirect3DDevice9_BeginScene(device);
9203 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9205 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
9206 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9207 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9208 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9209 ub_ok = SUCCEEDED(hr);
9211 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
9212 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9213 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
9214 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9216 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
9217 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9218 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
9219 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9220 ub_ok = (SUCCEEDED(hr) && ub_ok);
9222 hr = IDirect3DDevice9_EndScene(device);
9223 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9225 if(i == 0) {
9226 color = getPixelColor(device, 480, 360);
9227 ok(color == 0x00ff0000,
9228 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
9229 color = getPixelColor(device, 160, 120);
9230 ok(color == 0x00ffffff,
9231 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
9232 color = getPixelColor(device, 160, 360);
9233 ok(color == 0x000000ff || !ub_ok,
9234 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
9235 color = getPixelColor(device, 480, 120);
9236 ok(color == 0x000000ff || !ub_ok,
9237 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
9238 } else {
9239 color = getPixelColor(device, 480, 360);
9240 ok(color == 0x000000ff,
9241 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
9242 color = getPixelColor(device, 160, 120);
9243 ok(color == 0x00ffffff,
9244 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
9245 color = getPixelColor(device, 160, 360);
9246 ok(color == 0x00ff0000 || !ub_ok,
9247 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
9248 color = getPixelColor(device, 480, 120);
9249 ok(color == 0x00ff0000 || !ub_ok,
9250 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
9252 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9255 IDirect3DVertexBuffer9_Release(vb2);
9256 out:
9257 IDirect3DVertexBuffer9_Release(vb);
9258 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
9259 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
9260 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
9261 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
9262 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
9263 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
9264 IDirect3DVertexDeclaration9_Release(dcl_nocolor);
9265 IDirect3DVertexDeclaration9_Release(dcl_positiont);
9266 refcount = IDirect3DDevice9_Release(device);
9267 ok(!refcount, "Device has %u references left.\n", refcount);
9268 done:
9269 IDirect3D9_Release(d3d);
9270 DestroyWindow(window);
9273 static void test_vshader_float16(void)
9275 IDirect3DVertexDeclaration9 *vdecl = NULL;
9276 IDirect3DVertexBuffer9 *buffer = NULL;
9277 IDirect3DVertexShader9 *shader;
9278 IDirect3DDevice9 *device;
9279 IDirect3D9 *d3d;
9280 ULONG refcount;
9281 D3DCAPS9 caps;
9282 DWORD color;
9283 HWND window;
9284 void *data;
9285 HRESULT hr;
9287 static const D3DVERTEXELEMENT9 decl_elements[] =
9289 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9290 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9291 D3DDECL_END()
9293 static const DWORD shader_code[] =
9295 0xfffe0101, /* vs_1_1 */
9296 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9297 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
9298 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
9299 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
9300 0x0000ffff,
9302 static const struct vertex_float16color
9304 float x, y, z;
9305 DWORD c1, c2;
9307 quad[] =
9309 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
9310 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
9311 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
9312 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
9314 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
9315 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
9316 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
9317 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
9319 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
9320 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
9321 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
9322 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
9324 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
9325 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
9326 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
9327 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
9330 window = create_window();
9331 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9332 ok(!!d3d, "Failed to create a D3D object.\n");
9333 if (!(device = create_device(d3d, window, window, TRUE)))
9335 skip("Failed to create a D3D device, skipping tests.\n");
9336 goto done;
9339 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9340 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
9341 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
9343 skip("No vs_3_0 support, skipping tests.\n");
9344 IDirect3DDevice9_Release(device);
9345 goto done;
9348 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff102030, 1.0f, 0);
9349 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9351 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
9352 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
9353 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9354 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9355 hr = IDirect3DDevice9_SetVertexShader(device, shader);
9356 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9358 hr = IDirect3DDevice9_BeginScene(device);
9359 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9360 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
9361 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9362 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
9363 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9364 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
9365 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9366 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
9367 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9368 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
9369 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9370 hr = IDirect3DDevice9_EndScene(device);
9371 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9373 color = getPixelColor(device, 480, 360);
9374 ok(color == 0x00ff0000,
9375 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
9376 color = getPixelColor(device, 160, 120);
9377 ok(color == 0x00000000,
9378 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
9379 color = getPixelColor(device, 160, 360);
9380 ok(color == 0x0000ff00,
9381 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
9382 color = getPixelColor(device, 480, 120);
9383 ok(color == 0x000000ff,
9384 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
9385 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9387 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
9388 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9390 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
9391 D3DPOOL_MANAGED, &buffer, NULL);
9392 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
9393 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
9394 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
9395 memcpy(data, quad, sizeof(quad));
9396 hr = IDirect3DVertexBuffer9_Unlock(buffer);
9397 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
9398 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
9399 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
9401 hr = IDirect3DDevice9_BeginScene(device);
9402 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9403 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9404 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9405 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
9406 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9407 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
9408 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9409 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
9410 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9411 hr = IDirect3DDevice9_EndScene(device);
9412 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9414 color = getPixelColor(device, 480, 360);
9415 ok(color == 0x00ff0000,
9416 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
9417 color = getPixelColor(device, 160, 120);
9418 ok(color == 0x00000000,
9419 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
9420 color = getPixelColor(device, 160, 360);
9421 ok(color == 0x0000ff00,
9422 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
9423 color = getPixelColor(device, 480, 120);
9424 ok(color == 0x000000ff,
9425 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
9426 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9428 IDirect3DVertexDeclaration9_Release(vdecl);
9429 IDirect3DVertexShader9_Release(shader);
9430 IDirect3DVertexBuffer9_Release(buffer);
9431 refcount = IDirect3DDevice9_Release(device);
9432 ok(!refcount, "Device has %u references left.\n", refcount);
9433 done:
9434 IDirect3D9_Release(d3d);
9435 DestroyWindow(window);
9438 static void conditional_np2_repeat_test(void)
9440 IDirect3DTexture9 *texture;
9441 IDirect3DDevice9 *device;
9442 D3DLOCKED_RECT rect;
9443 unsigned int x, y;
9444 DWORD *dst, color;
9445 IDirect3D9 *d3d;
9446 ULONG refcount;
9447 D3DCAPS9 caps;
9448 HWND window;
9449 HRESULT hr;
9451 static const float quad[] =
9453 -1.0f, -1.0f, 0.1f, -0.2f, -0.2f,
9454 -1.0f, 1.0f, 0.1f, -0.2f, 1.2f,
9455 1.0f, -1.0f, 0.1f, 1.2f, -0.2f,
9456 1.0f, 1.0f, 0.1f, 1.2f, 1.2f,
9459 window = create_window();
9460 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9461 ok(!!d3d, "Failed to create a D3D object.\n");
9462 if (!(device = create_device(d3d, window, window, TRUE)))
9464 skip("Failed to create a D3D device, skipping tests.\n");
9465 goto done;
9468 memset(&caps, 0, sizeof(caps));
9469 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9470 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
9471 if (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)
9473 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
9474 ok(caps.TextureCaps & D3DPTEXTURECAPS_POW2,
9475 "Card has conditional NP2 support without power of two restriction set\n");
9477 else if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
9479 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
9480 IDirect3DDevice9_Release(device);
9481 goto done;
9483 else
9485 skip("Card has unconditional NP2 support, skipping conditional NP2 tests\n");
9486 IDirect3DDevice9_Release(device);
9487 goto done;
9490 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
9491 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9493 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9494 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9496 memset(&rect, 0, sizeof(rect));
9497 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
9498 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9499 for(y = 0; y < 10; y++) {
9500 for(x = 0; x < 10; x++) {
9501 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
9502 if(x == 0 || x == 9 || y == 0 || y == 9) {
9503 *dst = 0x00ff0000;
9504 } else {
9505 *dst = 0x000000ff;
9509 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9510 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9512 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
9513 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9514 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9515 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
9516 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
9517 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
9518 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
9519 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
9520 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9521 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
9523 hr = IDirect3DDevice9_BeginScene(device);
9524 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9525 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9526 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9527 hr = IDirect3DDevice9_EndScene(device);
9528 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9530 color = getPixelColor(device, 1, 1);
9531 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
9532 color = getPixelColor(device, 639, 479);
9533 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
9535 color = getPixelColor(device, 135, 101);
9536 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
9537 color = getPixelColor(device, 140, 101);
9538 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
9539 color = getPixelColor(device, 135, 105);
9540 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
9541 color = getPixelColor(device, 140, 105);
9542 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
9544 color = getPixelColor(device, 135, 376);
9545 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
9546 color = getPixelColor(device, 140, 376);
9547 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
9548 color = getPixelColor(device, 135, 379);
9549 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
9550 color = getPixelColor(device, 140, 379);
9551 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
9553 color = getPixelColor(device, 500, 101);
9554 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
9555 color = getPixelColor(device, 504, 101);
9556 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
9557 color = getPixelColor(device, 500, 105);
9558 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
9559 color = getPixelColor(device, 504, 105);
9560 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
9562 color = getPixelColor(device, 500, 376);
9563 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
9564 color = getPixelColor(device, 504, 376);
9565 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
9566 color = getPixelColor(device, 500, 380);
9567 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
9568 color = getPixelColor(device, 504, 380);
9569 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
9571 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9573 IDirect3DTexture9_Release(texture);
9574 refcount = IDirect3DDevice9_Release(device);
9575 ok(!refcount, "Device has %u references left.\n", refcount);
9576 done:
9577 IDirect3D9_Release(d3d);
9578 DestroyWindow(window);
9581 static void vface_register_test(void)
9583 IDirect3DSurface9 *surface, *backbuffer;
9584 IDirect3DVertexShader9 *vshader;
9585 IDirect3DPixelShader9 *shader;
9586 IDirect3DTexture9 *texture;
9587 IDirect3DDevice9 *device;
9588 IDirect3D9 *d3d;
9589 ULONG refcount;
9590 D3DCAPS9 caps;
9591 DWORD color;
9592 HWND window;
9593 HRESULT hr;
9595 static const DWORD shader_code[] =
9597 0xffff0300, /* ps_3_0 */
9598 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9599 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
9600 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
9601 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
9602 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
9603 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
9604 0x0000ffff /* END */
9606 static const DWORD vshader_code[] =
9608 0xfffe0300, /* vs_3_0 */
9609 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9610 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
9611 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
9612 0x0000ffff /* end */
9614 static const float quad[] =
9616 -1.0f, -1.0f, 0.1f,
9617 1.0f, -1.0f, 0.1f,
9618 -1.0f, 0.0f, 0.1f,
9620 1.0f, -1.0f, 0.1f,
9621 1.0f, 0.0f, 0.1f,
9622 -1.0f, 0.0f, 0.1f,
9624 -1.0f, 0.0f, 0.1f,
9625 -1.0f, 1.0f, 0.1f,
9626 1.0f, 0.0f, 0.1f,
9628 1.0f, 0.0f, 0.1f,
9629 -1.0f, 1.0f, 0.1f,
9630 1.0f, 1.0f, 0.1f,
9632 static const float blit[] =
9634 0.0f, -1.0f, 0.1f, 0.0f, 0.0f,
9635 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
9636 0.0f, 1.0f, 0.1f, 0.0f, 1.0f,
9637 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
9640 window = create_window();
9641 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9642 ok(!!d3d, "Failed to create a D3D object.\n");
9643 if (!(device = create_device(d3d, window, window, TRUE)))
9645 skip("Failed to create a D3D device, skipping tests.\n");
9646 goto done;
9649 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9650 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
9651 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
9653 skip("No shader model 3 support, skipping tests.\n");
9654 IDirect3DDevice9_Release(device);
9655 goto done;
9658 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
9659 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9660 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
9661 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
9662 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
9663 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9664 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
9665 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
9666 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
9667 ok(SUCCEEDED(hr), "Failed to set cull mode, hr %#x.\n", hr);
9668 hr = IDirect3DDevice9_SetPixelShader(device, shader);
9669 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
9670 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
9671 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9672 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9673 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
9674 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9675 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
9677 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
9678 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9680 hr = IDirect3DDevice9_BeginScene(device);
9681 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9683 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
9684 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
9685 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
9686 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9687 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9688 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
9689 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9690 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9691 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
9692 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
9693 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9695 /* Blit the texture onto the back buffer to make it visible */
9696 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9697 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
9698 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9699 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9700 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
9701 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
9702 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9703 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
9704 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9705 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
9706 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9707 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9708 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
9709 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9711 hr = IDirect3DDevice9_EndScene(device);
9712 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9714 color = getPixelColor(device, 160, 360);
9715 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
9716 color = getPixelColor(device, 160, 120);
9717 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
9718 color = getPixelColor(device, 480, 360);
9719 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
9720 color = getPixelColor(device, 480, 120);
9721 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
9722 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9723 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
9725 IDirect3DPixelShader9_Release(shader);
9726 IDirect3DVertexShader9_Release(vshader);
9727 IDirect3DSurface9_Release(surface);
9728 IDirect3DSurface9_Release(backbuffer);
9729 IDirect3DTexture9_Release(texture);
9730 refcount = IDirect3DDevice9_Release(device);
9731 ok(!refcount, "Device has %u references left.\n", refcount);
9732 done:
9733 IDirect3D9_Release(d3d);
9734 DestroyWindow(window);
9737 static void fixed_function_bumpmap_test(void)
9739 IDirect3DVertexDeclaration9 *vertex_declaration;
9740 IDirect3DTexture9 *texture, *tex1, *tex2;
9741 D3DLOCKED_RECT locked_rect;
9742 IDirect3DDevice9 *device;
9743 BOOL L6V5U5_supported;
9744 float scale, offset;
9745 IDirect3D9 *d3d;
9746 unsigned int i;
9747 D3DCOLOR color;
9748 ULONG refcount;
9749 D3DCAPS9 caps;
9750 HWND window;
9751 HRESULT hr;
9753 static const float quad[][7] =
9755 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
9756 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
9757 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
9758 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
9760 static const D3DVERTEXELEMENT9 decl_elements[] =
9762 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9763 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9764 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
9765 D3DDECL_END()
9767 /* use asymmetric matrix to test loading */
9768 static const float bumpenvmat[4] = {0.0f, 0.5f, -0.5f, 0.0f};
9770 window = create_window();
9771 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9772 ok(!!d3d, "Failed to create a D3D object.\n");
9773 if (!(device = create_device(d3d, window, window, TRUE)))
9775 skip("Failed to create a D3D device, skipping tests.\n");
9776 goto done;
9779 memset(&caps, 0, sizeof(caps));
9780 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9781 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
9782 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP))
9784 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
9785 IDirect3DDevice9_Release(device);
9786 goto done;
9789 /* This check is disabled, some Windows drivers do not handle
9790 * D3DUSAGE_QUERY_LEGACYBUMPMAP properly. They report that it is not
9791 * supported, but after that bump mapping works properly. So just test if
9792 * the format is generally supported, and check the BUMPENVMAP flag. */
9793 L6V5U5_supported = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
9794 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_L6V5U5));
9795 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
9796 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_V8U8)))
9798 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
9799 IDirect3DDevice9_Release(device);
9800 return;
9803 /* Generate the textures */
9804 generate_bumpmap_textures(device);
9806 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
9807 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9808 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
9809 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9810 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
9811 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9812 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
9813 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9815 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
9816 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9817 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
9818 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9819 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
9820 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9822 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9823 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9824 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9825 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9826 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
9827 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9829 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9830 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9832 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9833 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
9835 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff00ff, 1.0f, 0);
9836 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
9838 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9839 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
9840 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9841 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
9843 hr = IDirect3DDevice9_BeginScene(device);
9844 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
9846 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9847 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
9849 hr = IDirect3DDevice9_EndScene(device);
9850 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
9852 color = getPixelColor(device, 240, 60);
9853 ok(color_match(color, 0x005ea000, 4), "Got unexpected color 0x%08x.\n", color);
9854 color = getPixelColor(device, 400, 60);
9855 ok(color_match(color, 0x009ea000, 4), "Got unexpected color 0x%08x.\n", color);
9856 color = getPixelColor(device, 80, 180);
9857 ok(color_match(color, 0x005ea000, 4), "Got unexpected color 0x%08x.\n", color);
9858 color = getPixelColor(device, 560, 180);
9859 ok(color_match(color, 0x009ea000, 4), "Got unexpected color 0x%08x.\n", color);
9860 color = getPixelColor(device, 80, 300);
9861 ok(color_match(color, 0x005e6000, 4), "Got unexpected color 0x%08x.\n", color);
9862 color = getPixelColor(device, 560, 300);
9863 ok(color_match(color, 0x009e6000, 4), "Got unexpected color 0x%08x.\n", color);
9864 color = getPixelColor(device, 240, 420);
9865 ok(color_match(color, 0x005e6000, 4), "Got unexpected color 0x%08x.\n", color);
9866 color = getPixelColor(device, 400, 420);
9867 ok(color_match(color, 0x009e6000, 4), "Got unexpected color 0x%08x.\n", color);
9868 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9869 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9871 for(i = 0; i < 2; i++) {
9872 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
9873 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
9874 IDirect3DTexture9_Release(texture); /* For the GetTexture */
9875 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
9876 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
9877 IDirect3DTexture9_Release(texture); /* To destroy it */
9880 if (!L6V5U5_supported || !(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE))
9882 skip("L6V5U5 / D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping tests.\n");
9883 IDirect3DVertexDeclaration9_Release(vertex_declaration);
9884 IDirect3DDevice9_Release(device);
9885 goto done;
9888 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9889 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
9890 /* This test only tests the luminance part. The bumpmapping part was already tested above and
9891 * would only make this test more complicated
9893 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
9894 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9895 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
9896 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9898 memset(&locked_rect, 0, sizeof(locked_rect));
9899 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
9900 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9901 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
9902 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
9903 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9905 memset(&locked_rect, 0, sizeof(locked_rect));
9906 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
9907 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9908 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
9909 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
9910 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9912 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9913 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
9914 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
9915 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
9917 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
9918 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9919 scale = 2.0;
9920 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
9921 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9922 offset = 0.1;
9923 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
9924 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9926 hr = IDirect3DDevice9_BeginScene(device);
9927 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9928 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9929 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9930 hr = IDirect3DDevice9_EndScene(device);
9931 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9933 color = getPixelColor(device, 320, 240);
9934 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
9935 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
9936 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
9938 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
9939 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9940 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9942 /* Check a result scale factor > 1.0 */
9943 scale = 10;
9944 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
9945 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9946 offset = 10;
9947 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
9948 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9950 hr = IDirect3DDevice9_BeginScene(device);
9951 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9952 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9953 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9954 hr = IDirect3DDevice9_EndScene(device);
9955 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9957 color = getPixelColor(device, 320, 240);
9958 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
9959 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9960 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9962 /* Check clamping in the scale factor calculation */
9963 scale = 1000;
9964 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
9965 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9966 offset = -1;
9967 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
9968 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9970 hr = IDirect3DDevice9_BeginScene(device);
9971 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9972 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9973 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9974 hr = IDirect3DDevice9_EndScene(device);
9975 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9977 color = getPixelColor(device, 320, 240);
9978 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
9979 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9980 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9982 IDirect3DTexture9_Release(tex1);
9983 IDirect3DTexture9_Release(tex2);
9984 IDirect3DVertexDeclaration9_Release(vertex_declaration);
9985 refcount = IDirect3DDevice9_Release(device);
9986 ok(!refcount, "Device has %u references left.\n", refcount);
9987 done:
9988 IDirect3D9_Release(d3d);
9989 DestroyWindow(window);
9992 static void stencil_cull_test(void)
9994 IDirect3DDevice9 *device;
9995 IDirect3D9 *d3d;
9996 ULONG refcount;
9997 D3DCAPS9 caps;
9998 HWND window;
9999 HRESULT hr;
10000 static const float quad1[] =
10002 -1.0, -1.0, 0.1,
10003 0.0, -1.0, 0.1,
10004 -1.0, 0.0, 0.1,
10005 0.0, 0.0, 0.1,
10007 static const float quad2[] =
10009 0.0, -1.0, 0.1,
10010 1.0, -1.0, 0.1,
10011 0.0, 0.0, 0.1,
10012 1.0, 0.0, 0.1,
10014 static const float quad3[] =
10016 0.0, 0.0, 0.1,
10017 1.0, 0.0, 0.1,
10018 0.0, 1.0, 0.1,
10019 1.0, 1.0, 0.1,
10021 static const float quad4[] =
10023 -1.0, 0.0, 0.1,
10024 0.0, 0.0, 0.1,
10025 -1.0, 1.0, 0.1,
10026 0.0, 1.0, 0.1,
10028 struct
10030 struct vec3 position;
10031 DWORD diffuse;
10033 painter[] =
10035 {{-1.0f, -1.0f, 0.0f}, 0x00000000},
10036 {{ 1.0f, -1.0f, 0.0f}, 0x00000000},
10037 {{-1.0f, 1.0f, 0.0f}, 0x00000000},
10038 {{ 1.0f, 1.0f, 0.0f}, 0x00000000},
10040 static const WORD indices_cw[] = {0, 1, 3};
10041 static const WORD indices_ccw[] = {0, 2, 3};
10042 unsigned int i;
10043 DWORD color;
10045 window = create_window();
10046 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10047 ok(!!d3d, "Failed to create a D3D object.\n");
10048 if (!(device = create_device(d3d, window, window, TRUE)))
10050 skip("Cannot create a device with a D24S8 stencil buffer.\n");
10051 DestroyWindow(window);
10052 IDirect3D9_Release(d3d);
10053 return;
10055 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10056 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
10057 if (!(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED))
10059 skip("No two sided stencil support\n");
10060 goto cleanup;
10063 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
10064 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10065 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10066 ok(SUCCEEDED(hr), "Failed to set FVF,hr %#x.\n", hr);
10068 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10069 ok(hr == D3D_OK, "Failed to disable Z test, %#x.\n", hr);
10070 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10071 ok(hr == D3D_OK, "Failed to disable lighting, %#x.\n", hr);
10072 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
10073 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10074 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
10075 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10076 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
10077 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10078 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
10079 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10081 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
10082 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10083 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
10084 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10085 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
10086 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10088 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
10089 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10090 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
10091 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10093 /* First pass: Fill the stencil buffer with some values... */
10094 hr = IDirect3DDevice9_BeginScene(device);
10095 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10097 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
10098 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10099 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10100 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
10101 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10102 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10103 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
10104 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10106 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
10107 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10108 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
10109 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10110 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10111 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
10112 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10113 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10114 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
10115 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10117 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
10118 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10119 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10120 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
10121 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10122 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10123 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
10124 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10126 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
10127 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10128 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10129 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
10130 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10131 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10132 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
10133 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10135 hr = IDirect3DDevice9_EndScene(device);
10136 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10138 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
10139 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10140 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
10141 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10142 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
10143 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10144 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
10145 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10146 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
10147 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10148 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
10149 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10151 /* 2nd pass: Make the stencil values visible */
10152 hr = IDirect3DDevice9_BeginScene(device);
10153 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10154 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10155 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
10156 for (i = 0; i < 16; ++i)
10158 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
10159 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10161 painter[0].diffuse = (i * 16); /* Creates shades of blue */
10162 painter[1].diffuse = (i * 16);
10163 painter[2].diffuse = (i * 16);
10164 painter[3].diffuse = (i * 16);
10165 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
10166 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10168 hr = IDirect3DDevice9_EndScene(device);
10169 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10171 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
10172 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10174 color = getPixelColor(device, 160, 420);
10175 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
10176 color = getPixelColor(device, 160, 300);
10177 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
10179 color = getPixelColor(device, 480, 420);
10180 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
10181 color = getPixelColor(device, 480, 300);
10182 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
10184 color = getPixelColor(device, 160, 180);
10185 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
10186 color = getPixelColor(device, 160, 60);
10187 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
10189 color = getPixelColor(device, 480, 180);
10190 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
10191 color = getPixelColor(device, 480, 60);
10192 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
10194 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10195 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10197 cleanup:
10198 refcount = IDirect3DDevice9_Release(device);
10199 ok(!refcount, "Device has %u references left.\n", refcount);
10200 IDirect3D9_Release(d3d);
10201 DestroyWindow(window);
10204 static void test_fragment_coords(void)
10206 IDirect3DSurface9 *surface = NULL, *backbuffer;
10207 IDirect3DPixelShader9 *shader, *shader_frac;
10208 IDirect3DVertexShader9 *vshader;
10209 IDirect3DDevice9 *device;
10210 D3DLOCKED_RECT lr;
10211 IDirect3D9 *d3d;
10212 ULONG refcount;
10213 D3DCAPS9 caps;
10214 DWORD color;
10215 HWND window;
10216 HRESULT hr;
10217 DWORD *pos;
10219 static const DWORD shader_code[] =
10221 0xffff0300, /* ps_3_0 */
10222 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
10223 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
10224 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
10225 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
10226 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
10227 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
10228 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
10229 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
10230 0x0000ffff /* end */
10232 static const DWORD shader_frac_code[] =
10234 0xffff0300, /* ps_3_0 */
10235 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
10236 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
10237 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
10238 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
10239 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
10240 0x0000ffff /* end */
10242 static const DWORD vshader_code[] =
10244 0xfffe0300, /* vs_3_0 */
10245 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10246 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
10247 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
10248 0x0000ffff /* end */
10250 static const float quad[] =
10252 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
10253 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
10254 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
10255 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
10257 float constant[4] = {1.0, 0.0, 320, 240};
10259 window = create_window();
10260 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10261 ok(!!d3d, "Failed to create a D3D object.\n");
10262 if (!(device = create_device(d3d, window, window, TRUE)))
10264 skip("Failed to create a D3D device, skipping tests.\n");
10265 goto done;
10268 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10269 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
10270 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
10272 skip("No shader model 3 support, skipping tests.\n");
10273 IDirect3DDevice9_Release(device);
10274 goto done;
10277 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10278 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
10279 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
10280 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
10281 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
10282 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
10283 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
10284 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
10285 hr = IDirect3DDevice9_SetPixelShader(device, shader);
10286 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
10287 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
10288 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
10289 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10290 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
10291 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
10292 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
10294 hr = IDirect3DDevice9_BeginScene(device);
10295 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10296 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
10297 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
10298 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
10299 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10300 hr = IDirect3DDevice9_EndScene(device);
10301 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10303 /* This has to be pixel exact */
10304 color = getPixelColor(device, 319, 239);
10305 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
10306 color = getPixelColor(device, 320, 239);
10307 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
10308 color = getPixelColor(device, 319, 240);
10309 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
10310 color = getPixelColor(device, 320, 240);
10311 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
10312 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10314 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
10315 &surface, NULL);
10316 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
10317 hr = IDirect3DDevice9_BeginScene(device);
10318 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10319 constant[2] = 16; constant[3] = 16;
10320 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
10321 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
10322 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
10323 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10324 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
10325 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10326 hr = IDirect3DDevice9_EndScene(device);
10327 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10329 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
10330 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
10332 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
10333 color = *pos & 0x00ffffff;
10334 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
10335 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
10336 color = *pos & 0x00ffffff;
10337 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
10338 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
10339 color = *pos & 0x00ffffff;
10340 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
10341 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
10342 color = *pos & 0x00ffffff;
10343 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
10345 hr = IDirect3DSurface9_UnlockRect(surface);
10346 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
10348 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
10349 * have full control over the multisampling setting inside this test
10351 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
10352 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
10353 hr = IDirect3DDevice9_BeginScene(device);
10354 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10355 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
10356 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
10357 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
10358 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10359 hr = IDirect3DDevice9_EndScene(device);
10360 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10362 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10363 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
10365 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
10366 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
10368 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
10369 color = *pos & 0x00ffffff;
10370 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
10372 hr = IDirect3DSurface9_UnlockRect(surface);
10373 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
10375 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
10376 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
10377 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10378 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
10379 IDirect3DPixelShader9_Release(shader);
10380 IDirect3DPixelShader9_Release(shader_frac);
10381 IDirect3DVertexShader9_Release(vshader);
10382 if(surface) IDirect3DSurface9_Release(surface);
10383 IDirect3DSurface9_Release(backbuffer);
10384 refcount = IDirect3DDevice9_Release(device);
10385 ok(!refcount, "Device has %u references left.\n", refcount);
10386 done:
10387 IDirect3D9_Release(d3d);
10388 DestroyWindow(window);
10391 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
10393 D3DCOLOR color;
10395 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
10396 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
10397 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
10398 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
10399 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
10401 ++r;
10402 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
10403 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
10404 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
10405 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
10406 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
10408 return TRUE;
10411 static void test_pointsize(void)
10413 static const float a = 1.0f, b = 1.0f, c = 1.0f;
10414 float ptsize, ptsizemax_orig, ptsizemin_orig;
10415 IDirect3DSurface9 *rt, *backbuffer;
10416 IDirect3DTexture9 *tex1, *tex2;
10417 IDirect3DDevice9 *device;
10418 IDirect3DVertexShader9 *vs;
10419 IDirect3DPixelShader9 *ps;
10420 D3DLOCKED_RECT lr;
10421 IDirect3D9 *d3d;
10422 D3DCOLOR color;
10423 ULONG refcount;
10424 D3DCAPS9 caps;
10425 HWND window;
10426 HRESULT hr;
10427 unsigned int i, j;
10429 static const RECT rect = {0, 0, 128, 128};
10430 static const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000, 0x00000000, 0x00000000};
10431 static const DWORD tex2_data[4] = {0x00000000, 0x0000ff00, 0x00000000, 0x0000ff00};
10432 static const float vertices[] =
10434 64.0f, 64.0f, 0.1f,
10435 128.0f, 64.0f, 0.1f,
10436 192.0f, 64.0f, 0.1f,
10437 256.0f, 64.0f, 0.1f,
10438 320.0f, 64.0f, 0.1f,
10439 384.0f, 64.0f, 0.1f,
10440 448.0f, 64.0f, 0.1f,
10441 512.0f, 64.0f, 0.1f,
10443 static const struct
10445 float x, y, z;
10446 float point_size;
10448 vertex_pointsize = {64.0f, 64.0f, 0.1f, 48.0f},
10449 vertex_pointsize_scaled = {64.0f, 64.0f, 0.1f, 24.0f},
10450 vertex_pointsize_zero = {64.0f, 64.0f, 0.1f, 0.0f};
10451 /* Writing a texture coordinate from the shader is technically unnecessary, but is required
10452 * to make Windows AMD r500 drivers work. Without it, texture coordinates in the pixel
10453 * shaders are 0. */
10454 static const DWORD vshader_code[] =
10456 0xfffe0101, /* vs_1_1 */
10457 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10458 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10459 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10460 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10461 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
10462 0x00000001, 0xe00f0000, 0x90e40000, /* mov oT0, v0 */
10463 0x00000001, 0xe00f0001, 0x90e40000, /* mov oT1, v0 */
10464 0x0000ffff
10466 static const DWORD vshader_psize_code[] =
10468 0xfffe0101, /* vs_1_1 */
10469 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10470 0x0000001f, 0x80000004, 0x900f0001, /* dcl_psize v1 */
10471 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10472 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10473 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10474 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
10475 0x00000001, 0xc00f0002, 0x90000001, /* mov oPts, v1.x */
10476 0x00000001, 0xe00f0000, 0x90e40000, /* mov oT0, v0 */
10477 0x00000001, 0xe00f0001, 0x90e40000, /* mov oT1, v0 */
10478 0x0000ffff
10480 static const DWORD pshader_code[] =
10482 0xffff0101, /* ps_1_1 */
10483 0x00000042, 0xb00f0000, /* tex t0 */
10484 0x00000042, 0xb00f0001, /* tex t1 */
10485 0x00000002, 0x800f0000, 0xb0e40000, 0xb0e40001, /* add r0, t0, t1 */
10486 0x0000ffff
10488 static const DWORD pshader2_code[] =
10490 0xffff0200, /* ps_2_0 */
10491 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
10492 0x0200001f, 0x80000000, 0xb00f0001, /* dcl t1 */
10493 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10494 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10495 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
10496 0x03000042, 0x800f0001, 0xb0e40001, 0xa0e40801, /* texld r1, t1, s1 */
10497 0x03000002, 0x800f0000, 0x80e40000, 0x80e40001, /* add r0, r0, r1 */
10498 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
10499 0x0000ffff
10501 static const DWORD pshader2_zw_code[] =
10503 0xffff0200, /* ps_2_0 */
10504 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
10505 0x0200001f, 0x80000000, 0xb00f0001, /* dcl t1 */
10506 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10507 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10508 0x02000001, 0x80030000, 0xb01b0000, /* mov r0.xy, t0.wzyx */
10509 0x02000001, 0x80030001, 0xb01b0001, /* mov r1.xy, t1.wzyx */
10510 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, /* texld r0, r0, s0 */
10511 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40801, /* texld r1, r1, s1 */
10512 0x03000002, 0x800f0000, 0x80e40000, 0x80e40001, /* add r0, r0, r1 */
10513 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
10514 0x0000ffff
10516 static const DWORD vshader3_code[] =
10518 0xfffe0300, /* vs_3_0 */
10519 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10520 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
10521 0x0200001f, 0x80000005, 0xe00f0001, /* dcl_texcoord0 o1 */
10522 0x0200001f, 0x80010005, 0xe00f0002, /* dcl_texcoord1 o2 */
10523 0x03000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10524 0x04000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10525 0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10526 0x04000004, 0xe00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad o0, v0.w, c3, r0 */
10527 0x02000001, 0xe00f0001, 0x90000000, /* mov o1, v0.x */
10528 0x02000001, 0xe00f0002, 0x90000000, /* mov o2, v0.x */
10529 0x0000ffff
10531 static const DWORD vshader3_psize_code[] =
10533 0xfffe0300, /* vs_3_0 */
10534 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10535 0x0200001f, 0x80000004, 0x90010001, /* dcl_psize v1.x */
10536 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
10537 0x0200001f, 0x80000004, 0xe00f0001, /* dcl_psize o1 */
10538 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
10539 0x0200001f, 0x80010005, 0xe00f0003, /* dcl_texcoord1 o3 */
10540 0x03000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10541 0x04000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10542 0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10543 0x04000004, 0xe00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad o0, v0.w, c3, r0 */
10544 0x02000001, 0xe00f0001, 0x90000001, /* mov o1, v1.x */
10545 0x02000001, 0xe00f0002, 0x90000000, /* mov o2, v0.x */
10546 0x02000001, 0xe00f0003, 0x90000000, /* mov o3, v0.x */
10547 0x0000ffff
10549 static const DWORD pshader3_code[] =
10551 0xffff0300, /* ps_3_0 */
10552 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
10553 0x0200001f, 0x80010005, 0x900f0001, /* dcl_texcoord1 v1 */
10554 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10555 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10556 0x03000042, 0x800f0000, 0x90e40000, 0xa0e40800, /* texld r0, v0, s0 */
10557 0x03000042, 0x800f0001, 0x90e40001, 0xa0e40801, /* texld r1, v1, s1 */
10558 0x03000002, 0x800f0800, 0x80e40000, 0x80e40001, /* add oC0, r0, r1 */
10559 0x0000ffff
10561 static const DWORD pshader3_zw_code[] =
10563 0xffff0300, /* ps_3_0 */
10564 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
10565 0x0200001f, 0x80010005, 0x900f0001, /* dcl_texcoord1 v1 */
10566 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10567 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10568 0x03000042, 0x800f0000, 0x90fe0000, 0xa0e40800, /* texld r0, v0.zw, s0 */
10569 0x03000042, 0x800f0001, 0x90fe0001, 0xa0e40801, /* texld r1, v1.zw, s1 */
10570 0x03000002, 0x800f0800, 0x80e40000, 0x80e40001, /* add oC0, r0, r1 */
10571 0x0000ffff
10573 static const struct test_shader
10575 DWORD version;
10576 const DWORD *code;
10578 novs = {0, NULL},
10579 vs1 = {D3DVS_VERSION(1, 1), vshader_code},
10580 vs1_psize = {D3DVS_VERSION(1, 1), vshader_psize_code},
10581 vs3 = {D3DVS_VERSION(3, 0), vshader3_code},
10582 vs3_psize = {D3DVS_VERSION(3, 0), vshader3_psize_code},
10583 nops = {0, NULL},
10584 ps1 = {D3DPS_VERSION(1, 1), pshader_code},
10585 ps2 = {D3DPS_VERSION(2, 0), pshader2_code},
10586 ps2_zw = {D3DPS_VERSION(2, 0), pshader2_zw_code},
10587 ps3 = {D3DPS_VERSION(3, 0), pshader3_code},
10588 ps3_zw = {D3DPS_VERSION(3, 0), pshader3_zw_code};
10589 static const struct
10591 const struct test_shader *vs;
10592 const struct test_shader *ps;
10593 DWORD accepted_fvf;
10594 unsigned int nonscaled_size, scaled_size;
10595 BOOL gives_0_0_texcoord;
10596 BOOL allow_broken;
10598 test_setups[] =
10600 {&novs, &nops, D3DFVF_XYZ, 32, 45, FALSE, FALSE},
10601 {&vs1, &ps1, D3DFVF_XYZ, 32, 32, FALSE, FALSE},
10602 {&novs, &ps1, D3DFVF_XYZ, 32, 45, FALSE, FALSE},
10603 {&vs1, &nops, D3DFVF_XYZ, 32, 32, FALSE, FALSE},
10604 {&novs, &ps2, D3DFVF_XYZ, 32, 45, FALSE, TRUE},
10605 {&novs, &ps2_zw, D3DFVF_XYZ, 32, 45, TRUE, FALSE},
10606 {&vs1, &ps2, D3DFVF_XYZ, 32, 32, FALSE, TRUE},
10607 {&vs1, &ps2_zw, D3DFVF_XYZ, 32, 32, TRUE, FALSE},
10608 {&vs3, &ps3, D3DFVF_XYZ, 32, 32, FALSE, TRUE},
10609 {&vs3, &ps3_zw, D3DFVF_XYZ, 32, 32, TRUE, FALSE},
10610 {&novs, &nops, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 33, FALSE, FALSE},
10611 {&vs1_psize, &ps1, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 24, FALSE, FALSE},
10612 {&vs3_psize, &ps3, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 24, FALSE, TRUE},
10614 static const struct
10616 BOOL zero_size;
10617 BOOL scale;
10618 BOOL override_min;
10619 DWORD fvf;
10620 const void *vertex_data;
10621 unsigned int vertex_size;
10623 tests[] =
10625 {FALSE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10626 {FALSE, TRUE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10627 {FALSE, FALSE, TRUE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10628 {TRUE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10629 {FALSE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
10630 {FALSE, TRUE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_scaled, sizeof(vertex_pointsize_scaled)},
10631 {FALSE, FALSE, TRUE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
10632 {TRUE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_zero, sizeof(vertex_pointsize_zero)},
10634 /* Transforms the coordinate system [-1.0;1.0]x[1.0;-1.0] to
10635 * [0.0;0.0]x[640.0;480.0]. Z is untouched. */
10636 D3DMATRIX matrix =
10638 2.0f / 640.0f, 0.0f, 0.0f, 0.0f,
10639 0.0f, -2.0f / 480.0f, 0.0f, 0.0f,
10640 0.0f, 0.0f, 1.0f, 0.0f,
10641 -1.0f, 1.0f, 0.0f, 1.0f,
10642 }}};
10644 window = create_window();
10645 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10646 ok(!!d3d, "Failed to create a D3D object.\n");
10647 if (!(device = create_device(d3d, window, window, TRUE)))
10649 skip("Failed to create a D3D device, skipping tests.\n");
10650 goto done;
10653 memset(&caps, 0, sizeof(caps));
10654 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10655 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
10656 if(caps.MaxPointSize < 32.0) {
10657 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
10658 IDirect3DDevice9_Release(device);
10659 goto done;
10662 /* The r500 Windows driver needs a draw with regular texture coordinates at least once during the
10663 * device's lifetime, otherwise texture coordinate generation only works for texture 0. */
10664 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
10665 ok(SUCCEEDED(hr), "Failed to set FVF, hr=%#x.\n", hr);
10666 hr = IDirect3DDevice9_BeginScene(device);
10667 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10668 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, vertices, sizeof(float) * 5);
10669 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10670 hr = IDirect3DDevice9_EndScene(device);
10671 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10673 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10674 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
10675 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10676 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
10677 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
10678 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
10679 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10680 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
10682 hr = IDirect3DDevice9_BeginScene(device);
10683 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10685 ptsize = 15.0f;
10686 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10687 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10688 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
10689 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10691 ptsize = 31.0f;
10692 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10693 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10694 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
10695 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10697 ptsize = 30.75f;
10698 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10699 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10700 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
10701 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10703 if (caps.MaxPointSize >= 63.0f)
10705 ptsize = 63.0f;
10706 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10707 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10708 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
10709 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10711 ptsize = 62.75f;
10712 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10713 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10714 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
10715 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10718 ptsize = 1.0f;
10719 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10720 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10721 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
10722 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10724 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *)&ptsizemax_orig);
10725 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
10726 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *)&ptsizemin_orig);
10727 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
10729 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
10730 ptsize = 15.0f;
10731 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10732 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10733 ptsize = 1.0f;
10734 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsize);
10735 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10736 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
10737 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10739 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsizemax_orig);
10740 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10742 /* pointsize < pointsize_min < pointsize_max?
10743 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
10744 ptsize = 1.0f;
10745 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10746 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10747 ptsize = 15.0f;
10748 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
10749 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10750 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
10751 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10753 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsizemin_orig);
10754 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10756 hr = IDirect3DDevice9_EndScene(device);
10757 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10759 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
10760 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
10761 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
10763 if (caps.MaxPointSize >= 63.0)
10765 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
10766 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
10769 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
10770 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
10771 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
10772 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
10773 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
10775 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10777 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
10778 * generates texture coordinates for the point(result: Yes, it does)
10780 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
10781 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
10782 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
10784 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10785 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
10787 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
10788 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
10789 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
10790 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
10791 memset(&lr, 0, sizeof(lr));
10792 hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
10793 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
10794 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
10795 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
10796 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
10797 memset(&lr, 0, sizeof(lr));
10798 hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
10799 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
10800 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
10801 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
10802 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
10803 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
10804 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
10805 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
10806 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
10807 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10808 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10809 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10810 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10811 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
10812 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10813 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10814 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10815 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
10816 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10818 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
10819 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
10820 ptsize = 32.0;
10821 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
10822 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
10824 hr = IDirect3DDevice9_BeginScene(device);
10825 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10826 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
10827 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10828 hr = IDirect3DDevice9_EndScene(device);
10829 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10831 color = getPixelColor(device, 64-4, 64-4);
10832 ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
10833 color = getPixelColor(device, 64-4, 64+4);
10834 ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
10835 color = getPixelColor(device, 64+4, 64+4);
10836 ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
10837 color = getPixelColor(device, 64+4, 64-4);
10838 ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
10839 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10841 U(matrix).m[0][0] = 1.0f / 64.0f;
10842 U(matrix).m[1][1] = -1.0f / 64.0f;
10843 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
10844 ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
10846 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
10847 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10849 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
10850 D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
10851 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10853 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_A, *(DWORD *)&a);
10854 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
10855 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_B, *(DWORD *)&b);
10856 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
10857 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_C, *(DWORD *)&c);
10858 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
10859 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
10861 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, &S(U(matrix))._11, 4);
10862 ok(SUCCEEDED(hr), "Failed to set vertex shader constants, hr %#x.\n", hr);
10865 if (caps.MaxPointSize < 63.0f)
10867 skip("MaxPointSize %f < 63.0, skipping some tests.\n", caps.MaxPointSize);
10868 goto cleanup;
10871 for (i = 0; i < sizeof(test_setups) / sizeof(test_setups[0]); ++i)
10873 if (caps.VertexShaderVersion < test_setups[i].vs->version
10874 || caps.PixelShaderVersion < test_setups[i].ps->version)
10876 skip("Vertex / pixel shader version not supported, skipping test.\n");
10877 continue;
10879 if (test_setups[i].vs->code)
10881 hr = IDirect3DDevice9_CreateVertexShader(device, test_setups[i].vs->code, &vs);
10882 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
10884 else
10886 vs = NULL;
10888 if (test_setups[i].ps->code)
10890 hr = IDirect3DDevice9_CreatePixelShader(device, test_setups[i].ps->code, &ps);
10891 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
10893 else
10895 ps = NULL;
10898 hr = IDirect3DDevice9_SetVertexShader(device, vs);
10899 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
10900 hr = IDirect3DDevice9_SetPixelShader(device, ps);
10901 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
10903 for (j = 0; j < sizeof(tests) / sizeof(tests[0]); ++j)
10905 BOOL allow_broken = test_setups[i].allow_broken;
10906 unsigned int size = tests[j].override_min ? 63 : tests[j].zero_size ? 0 : tests[j].scale
10907 ? test_setups[i].scaled_size : test_setups[i].nonscaled_size;
10909 if (test_setups[i].accepted_fvf != tests[j].fvf)
10910 continue;
10912 ptsize = tests[j].zero_size ? 0.0f : 32.0f;
10913 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10914 ok(SUCCEEDED(hr), "Failed to set pointsize, hr %#x.\n", hr);
10916 ptsize = tests[j].override_min ? 63.0f : tests[j].zero_size ? 0.0f : ptsizemin_orig;
10917 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
10918 ok(SUCCEEDED(hr), "Failed to set minimum pointsize, hr %#x.\n", hr);
10920 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALEENABLE, tests[j].scale);
10921 ok(SUCCEEDED(hr), "Failed setting point scale state, hr %#x.\n", hr);
10923 hr = IDirect3DDevice9_SetFVF(device, tests[j].fvf);
10924 ok(SUCCEEDED(hr), "Failed setting FVF, hr %#x.\n", hr);
10926 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
10927 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10928 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
10929 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
10931 hr = IDirect3DDevice9_BeginScene(device);
10932 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10933 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1,
10934 tests[j].vertex_data, tests[j].vertex_size);
10935 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10936 hr = IDirect3DDevice9_EndScene(device);
10937 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10939 hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
10940 ok(SUCCEEDED(hr), "Failed to blit, hr %#x.\n", hr);
10941 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10942 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10944 if (tests[j].zero_size)
10946 /* Technically 0 pointsize is undefined in OpenGL but in practice it seems like
10947 * it does the "useful" thing on all the drivers I tried. */
10948 /* On WARP it does draw some pixels, most of the time. */
10949 color = getPixelColor(device, 64, 64);
10950 ok(color_match(color, 0x0000ffff, 0)
10951 || broken(color_match(color, 0x00ff0000, 0))
10952 || broken(color_match(color, 0x00ffff00, 0))
10953 || broken(color_match(color, 0x00000000, 0))
10954 || broken(color_match(color, 0x0000ff00, 0)),
10955 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10957 else
10959 struct surface_readback rb;
10961 get_rt_readback(backbuffer, &rb);
10962 /* On AMD apparently only the first texcoord is modified by the point coordinates
10963 * when using SM2/3 pixel shaders. */
10964 color = get_readback_color(&rb, 64 - size / 2 + 1, 64 - size / 2 + 1);
10965 ok(color_match(color, 0x00ff0000, 0),
10966 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10967 color = get_readback_color(&rb, 64 + size / 2 - 1, 64 - size / 2 + 1);
10968 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x00ffff00, 0)
10969 || (allow_broken && broken(color_match(color, 0x00ff0000, 0))),
10970 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10971 color = get_readback_color(&rb, 64 - size / 2 + 1, 64 + size / 2 - 1);
10972 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x00000000, 0),
10973 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10974 color = get_readback_color(&rb, 64 + size / 2 - 1, 64 + size / 2 - 1);
10975 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x0000ff00, 0)
10976 || (allow_broken && broken(color_match(color, 0x00000000, 0))),
10977 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10979 color = get_readback_color(&rb, 64 - size / 2 - 1, 64 - size / 2 - 1);
10980 ok(color_match(color, 0xff00ffff, 0),
10981 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10982 color = get_readback_color(&rb, 64 + size / 2 + 1, 64 - size / 2 - 1);
10983 ok(color_match(color, 0xff00ffff, 0),
10984 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10985 color = get_readback_color(&rb, 64 - size / 2 - 1, 64 + size / 2 + 1);
10986 ok(color_match(color, 0xff00ffff, 0),
10987 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10988 color = get_readback_color(&rb, 64 + size / 2 + 1, 64 + size / 2 + 1);
10989 ok(color_match(color, 0xff00ffff, 0),
10990 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10992 release_surface_readback(&rb);
10995 IDirect3DDevice9_SetVertexShader(device, NULL);
10996 IDirect3DDevice9_SetPixelShader(device, NULL);
10997 if (vs)
10998 IDirect3DVertexShader9_Release(vs);
10999 if (ps)
11000 IDirect3DVertexShader9_Release(ps);
11003 cleanup:
11004 IDirect3DSurface9_Release(backbuffer);
11005 IDirect3DSurface9_Release(rt);
11007 IDirect3DTexture9_Release(tex1);
11008 IDirect3DTexture9_Release(tex2);
11009 refcount = IDirect3DDevice9_Release(device);
11010 ok(!refcount, "Device has %u references left.\n", refcount);
11011 done:
11012 IDirect3D9_Release(d3d);
11013 DestroyWindow(window);
11016 static void multiple_rendertargets_test(void)
11018 IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
11019 IDirect3DPixelShader9 *ps1, *ps2;
11020 IDirect3DTexture9 *tex1, *tex2;
11021 IDirect3DVertexShader9 *vs;
11022 IDirect3DDevice9 *device;
11023 IDirect3D9 *d3d;
11024 ULONG refcount;
11025 D3DCAPS9 caps;
11026 DWORD color;
11027 HWND window;
11028 HRESULT hr;
11029 UINT i, j;
11031 static const DWORD vshader_code[] =
11033 0xfffe0300, /* vs_3_0 */
11034 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11035 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
11036 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
11037 0x0000ffff /* end */
11039 static const DWORD pshader_code1[] =
11041 0xffff0300, /* ps_3_0 */
11042 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
11043 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
11044 0x0000ffff /* end */
11046 static const DWORD pshader_code2[] =
11048 0xffff0300, /* ps_3_0 */
11049 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
11050 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
11051 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
11052 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
11053 0x0000ffff /* end */
11055 static const float quad[] =
11057 -1.0f, -1.0f, 0.1f,
11058 -1.0f, 1.0f, 0.1f,
11059 1.0f, -1.0f, 0.1f,
11060 1.0f, 1.0f, 0.1f,
11062 static const float texquad[] =
11064 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
11065 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
11066 0.0f, -1.0f, 0.1f, 1.0f, 0.0f,
11067 0.0f, 1.0f, 0.1f, 1.0f, 1.0f,
11069 0.0f, -1.0f, 0.1f, 0.0f, 0.0f,
11070 0.0f, 1.0f, 0.1f, 0.0f, 1.0f,
11071 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
11072 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
11075 window = create_window();
11076 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11077 ok(!!d3d, "Failed to create a D3D object.\n");
11078 if (!(device = create_device(d3d, window, window, TRUE)))
11080 skip("Failed to create a D3D device, skipping tests.\n");
11081 goto done;
11084 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11085 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
11086 if (caps.NumSimultaneousRTs < 2)
11088 skip("Only 1 simultaneous render target supported, skipping MRT test.\n");
11089 IDirect3DDevice9_Release(device);
11090 goto done;
11092 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
11094 skip("No shader model 3 support, skipping tests.\n");
11095 IDirect3DDevice9_Release(device);
11096 goto done;
11099 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
11100 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
11102 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
11103 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
11104 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
11106 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
11107 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
11108 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
11109 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
11110 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
11111 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
11112 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
11113 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
11114 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code1, &ps1);
11115 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
11116 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code2, &ps2);
11117 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
11119 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
11120 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
11121 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
11122 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
11123 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
11124 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
11126 hr = IDirect3DDevice9_SetVertexShader(device, vs);
11127 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
11128 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
11129 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11130 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
11131 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11132 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
11133 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
11135 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
11136 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
11137 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
11138 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11139 color = getPixelColorFromSurface(readback, 8, 8);
11140 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
11141 "Expected color 0x000000ff, got 0x%08x.\n", color);
11142 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
11143 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11144 color = getPixelColorFromSurface(readback, 8, 8);
11145 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
11146 "Expected color 0x000000ff, got 0x%08x.\n", color);
11148 /* Render targets not written by the pixel shader should be unmodified. */
11149 hr = IDirect3DDevice9_SetPixelShader(device, ps1);
11150 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
11151 hr = IDirect3DDevice9_BeginScene(device);
11152 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11153 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
11154 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11155 hr = IDirect3DDevice9_EndScene(device);
11156 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11157 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
11158 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11159 color = getPixelColorFromSurface(readback, 8, 8);
11160 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
11161 "Expected color 0xff00ff00, got 0x%08x.\n", color);
11162 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
11163 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11164 for (i = 6; i < 10; ++i)
11166 for (j = 6; j < 10; ++j)
11168 color = getPixelColorFromSurface(readback, j, i);
11169 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
11170 "Expected color 0xff0000ff, got 0x%08x at %u, %u.\n", color, j, i);
11174 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
11175 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
11176 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
11177 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11178 color = getPixelColorFromSurface(readback, 8, 8);
11179 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
11180 "Expected color 0x0000ff00, got 0x%08x.\n", color);
11181 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
11182 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11183 color = getPixelColorFromSurface(readback, 8, 8);
11184 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
11185 "Expected color 0x0000ff00, got 0x%08x.\n", color);
11187 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
11188 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
11190 hr = IDirect3DDevice9_BeginScene(device);
11191 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11193 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
11194 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11196 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11197 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11198 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11199 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
11200 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11201 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
11202 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
11203 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11204 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
11205 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11206 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11207 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
11209 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
11210 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
11211 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
11212 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11214 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
11215 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
11216 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
11217 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11219 hr = IDirect3DDevice9_EndScene(device);
11220 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11222 color = getPixelColor(device, 160, 240);
11223 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
11224 color = getPixelColor(device, 480, 240);
11225 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
11226 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11228 IDirect3DPixelShader9_Release(ps2);
11229 IDirect3DPixelShader9_Release(ps1);
11230 IDirect3DVertexShader9_Release(vs);
11231 IDirect3DTexture9_Release(tex1);
11232 IDirect3DTexture9_Release(tex2);
11233 IDirect3DSurface9_Release(surf1);
11234 IDirect3DSurface9_Release(surf2);
11235 IDirect3DSurface9_Release(backbuf);
11236 IDirect3DSurface9_Release(readback);
11237 refcount = IDirect3DDevice9_Release(device);
11238 ok(!refcount, "Device has %u references left.\n", refcount);
11239 done:
11240 IDirect3D9_Release(d3d);
11241 DestroyWindow(window);
11244 static void pixelshader_blending_test(void)
11246 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
11247 IDirect3DTexture9 *offscreenTexture = NULL;
11248 IDirect3DDevice9 *device;
11249 IDirect3D9 *d3d;
11250 ULONG refcount;
11251 int fmt_index;
11252 DWORD color;
11253 HWND window;
11254 HRESULT hr;
11256 static const struct
11258 const char *fmtName;
11259 D3DFORMAT textureFormat;
11260 D3DCOLOR resultColorBlending;
11261 D3DCOLOR resultColorNoBlending;
11263 test_formats[] =
11265 {"D3DFMT_G16R16", D3DFMT_G16R16, 0x001820ff, 0x002010ff},
11266 {"D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff},
11267 {"D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001820ff, 0x002010ff},
11268 {"D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00182000, 0x00201000},
11269 {"D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff},
11270 {"D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001820ff, 0x002010ff},
11271 {"D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00182000, 0x00201000},
11272 {"D3DFMT_L8", D3DFMT_L8, 0x00181818, 0x00202020},
11274 static const float quad[][5] =
11276 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
11277 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
11278 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
11279 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
11281 static const struct
11283 struct vec3 position;
11284 DWORD diffuse;
11286 quad1[] =
11288 {{-1.0f, -1.0f, 0.1f}, 0x80103000},
11289 {{-1.0f, 1.0f, 0.1f}, 0x80103000},
11290 {{ 1.0f, -1.0f, 0.1f}, 0x80103000},
11291 {{ 1.0f, 1.0f, 0.1f}, 0x80103000},
11293 quad2[] =
11295 {{-1.0f, -1.0f, 0.1f}, 0x80201000},
11296 {{-1.0f, 1.0f, 0.1f}, 0x80201000},
11297 {{ 1.0f, -1.0f, 0.1f}, 0x80201000},
11298 {{ 1.0f, 1.0f, 0.1f}, 0x80201000},
11301 window = create_window();
11302 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11303 ok(!!d3d, "Failed to create a D3D object.\n");
11304 if (!(device = create_device(d3d, window, window, TRUE)))
11306 skip("Failed to create a D3D device, skipping tests.\n");
11307 goto done;
11310 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
11311 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
11313 for (fmt_index = 0; fmt_index < sizeof(test_formats) / sizeof(*test_formats); ++fmt_index)
11315 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
11317 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11318 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
11320 skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
11321 continue;
11324 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
11325 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
11327 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
11328 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
11329 if(!offscreenTexture) {
11330 continue;
11333 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
11334 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
11335 if(!offscreen) {
11336 continue;
11339 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11340 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
11342 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11343 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11344 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
11345 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11346 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11347 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
11348 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11349 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
11350 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11351 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
11353 /* Below we will draw two quads with different colors and try to blend
11354 * them together. The result color is compared with the expected
11355 * outcome. */
11356 hr = IDirect3DDevice9_BeginScene(device);
11357 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11359 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
11360 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11361 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 1.0f, 0);
11362 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
11364 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
11365 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11367 /* Draw a quad using color 0x0010200. */
11368 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
11369 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11370 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
11371 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11372 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
11373 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11375 /* Draw a quad using color 0x0020100. */
11376 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
11377 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11378 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
11379 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11380 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
11381 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11383 /* We don't want to blend the result on the backbuffer. */
11384 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
11385 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11387 /* Prepare rendering the 'blended' texture quad to the backbuffer. */
11388 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11389 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11390 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)offscreenTexture);
11391 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
11393 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11394 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
11396 /* This time with the texture. */
11397 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
11398 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11400 hr = IDirect3DDevice9_EndScene(device);
11401 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11403 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11404 D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK)
11406 /* Compare the color of the center quad with our expectation. */
11407 color = getPixelColor(device, 320, 240);
11408 ok(color_match(color, test_formats[fmt_index].resultColorBlending, 1),
11409 "Offscreen failed for %s: Got color 0x%08x, expected 0x%08x.\n",
11410 test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
11412 else
11414 /* No pixel shader blending is supported so expect garbage. The
11415 * type of 'garbage' depends on the driver version and OS. E.g. on
11416 * G16R16 ATI reports (on old r9600 drivers) 0x00ffffff and on
11417 * modern ones 0x002010ff which is also what NVIDIA reports. On
11418 * Vista NVIDIA seems to report 0x00ffffff on Geforce7 cards. */
11419 color = getPixelColor(device, 320, 240);
11420 ok((color == 0x00ffffff) || (color == test_formats[fmt_index].resultColorNoBlending),
11421 "Offscreen failed for %s: Got unexpected color 0x%08x, expected no color blending.\n",
11422 test_formats[fmt_index].fmtName, color);
11424 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11426 IDirect3DDevice9_SetTexture(device, 0, NULL);
11427 if(offscreenTexture) {
11428 IDirect3DTexture9_Release(offscreenTexture);
11430 if(offscreen) {
11431 IDirect3DSurface9_Release(offscreen);
11435 IDirect3DSurface9_Release(backbuffer);
11436 refcount = IDirect3DDevice9_Release(device);
11437 ok(!refcount, "Device has %u references left.\n", refcount);
11438 done:
11439 IDirect3D9_Release(d3d);
11440 DestroyWindow(window);
11443 static void tssargtemp_test(void)
11445 IDirect3DDevice9 *device;
11446 IDirect3D9 *d3d;
11447 D3DCOLOR color;
11448 ULONG refcount;
11449 D3DCAPS9 caps;
11450 HWND window;
11451 HRESULT hr;
11453 static const struct
11455 struct vec3 position;
11456 DWORD diffuse;
11458 quad[] =
11460 {{-1.0f, -1.0f, 0.1f}, 0x00ff0000},
11461 {{-1.0f, 1.0f, 0.1f}, 0x00ff0000},
11462 {{ 1.0f, -1.0f, 0.1f}, 0x00ff0000},
11463 {{ 1.0f, 1.0f, 0.1f}, 0x00ff0000},
11466 window = create_window();
11467 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11468 ok(!!d3d, "Failed to create a D3D object.\n");
11469 if (!(device = create_device(d3d, window, window, TRUE)))
11471 skip("Failed to create a D3D device, skipping tests.\n");
11472 goto done;
11475 memset(&caps, 0, sizeof(caps));
11476 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11477 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
11478 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
11479 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
11480 IDirect3DDevice9_Release(device);
11481 goto done;
11484 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
11485 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11487 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11488 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11489 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
11490 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11492 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11493 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11494 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
11495 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11496 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
11497 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11499 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
11500 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11501 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
11502 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11503 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
11504 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11506 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
11507 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11509 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
11510 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
11511 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11512 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
11513 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11514 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
11516 hr = IDirect3DDevice9_BeginScene(device);
11517 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11518 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
11519 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11520 hr = IDirect3DDevice9_EndScene(device);
11521 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11523 color = getPixelColor(device, 320, 240);
11524 ok(color == 0x00ffff00, "TSSARGTEMP test returned color 0x%08x, expected 0x00ffff00\n", color);
11525 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11527 refcount = IDirect3DDevice9_Release(device);
11528 ok(!refcount, "Device has %u references left.\n", refcount);
11529 done:
11530 IDirect3D9_Release(d3d);
11531 DestroyWindow(window);
11534 /* Drawing Indexed Geometry with instances*/
11535 static void stream_test(void)
11537 IDirect3DVertexDeclaration9 *pDecl = NULL;
11538 IDirect3DVertexShader9 *shader = NULL;
11539 IDirect3DVertexBuffer9 *vb3 = NULL;
11540 IDirect3DVertexBuffer9 *vb2 = NULL;
11541 IDirect3DVertexBuffer9 *vb = NULL;
11542 IDirect3DIndexBuffer9 *ib = NULL;
11543 IDirect3DDevice9 *device;
11544 IDirect3D9 *d3d;
11545 ULONG refcount;
11546 D3DCAPS9 caps;
11547 DWORD color;
11548 HWND window;
11549 unsigned i;
11550 HRESULT hr;
11551 BYTE *data;
11552 DWORD ind;
11554 static const struct testdata
11556 DWORD idxVertex; /* number of instances in the first stream */
11557 DWORD idxColor; /* number of instances in the second stream */
11558 DWORD idxInstance; /* should be 1 ?? */
11559 DWORD color1; /* color 1 instance */
11560 DWORD color2; /* color 2 instance */
11561 DWORD color3; /* color 3 instance */
11562 DWORD color4; /* color 4 instance */
11563 WORD strVertex; /* specify which stream to use 0-2*/
11564 WORD strColor;
11565 WORD strInstance;
11567 testcases[]=
11569 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
11570 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
11571 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
11572 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
11573 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 4 */
11574 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
11575 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
11576 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
11577 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 8 */
11578 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 9 */
11579 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 10 */
11580 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 11 */
11581 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 12 */
11582 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 13 */
11583 #if 0
11584 /* This draws one instance on some machines, no instance on others. */
11585 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 14 */
11586 /* This case is handled in a stand alone test,
11587 * SetStreamSourceFreq(0, (D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to
11588 * return D3DERR_INVALIDCALL. */
11589 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0}, /* 15 */
11590 #endif
11592 static const DWORD shader_code[] =
11594 0xfffe0101, /* vs_1_1 */
11595 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11596 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
11597 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
11598 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
11599 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
11600 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
11601 0x0000ffff
11603 static const float quad[][3] =
11605 {-0.5f, -0.5f, 1.1f}, /*0 */
11606 {-0.5f, 0.5f, 1.1f}, /*1 */
11607 { 0.5f, -0.5f, 1.1f}, /*2 */
11608 { 0.5f, 0.5f, 1.1f}, /*3 */
11610 static const float vertcolor[][4] =
11612 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
11613 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
11614 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
11615 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
11617 /* 4 position for 4 instances */
11618 static const float instancepos[][3] =
11620 {-0.6f,-0.6f, 0.0f},
11621 { 0.6f,-0.6f, 0.0f},
11622 { 0.6f, 0.6f, 0.0f},
11623 {-0.6f, 0.6f, 0.0f},
11625 static const short indices[] = {0, 1, 2, 2, 1, 3};
11626 D3DVERTEXELEMENT9 decl[] =
11628 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
11629 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
11630 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
11631 D3DDECL_END()
11634 window = create_window();
11635 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11636 ok(!!d3d, "Failed to create a D3D object.\n");
11637 if (!(device = create_device(d3d, window, window, TRUE)))
11639 skip("Failed to create a D3D device, skipping tests.\n");
11640 goto done;
11643 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11644 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
11645 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
11647 skip("No vs_3_0 support, skipping tests.\n");
11648 IDirect3DDevice9_Release(device);
11649 goto done;
11652 /* set the default value because it isn't done in wine? */
11653 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
11654 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11656 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
11657 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
11658 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11660 /* check wrong cases */
11661 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
11662 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11663 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11664 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11665 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
11666 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11667 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11668 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11669 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
11670 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11671 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11672 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11673 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
11674 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11675 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11676 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11677 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
11678 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11679 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11680 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11682 /* set the default value back */
11683 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
11684 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11686 /* create all VertexBuffers*/
11687 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
11688 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
11689 if(!vb) {
11690 skip("Failed to create a vertex buffer\n");
11691 IDirect3DDevice9_Release(device);
11692 goto done;
11694 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
11695 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
11696 if(!vb2) {
11697 skip("Failed to create a vertex buffer\n");
11698 goto out;
11700 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
11701 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
11702 if(!vb3) {
11703 skip("Failed to create a vertex buffer\n");
11704 goto out;
11707 /* create IndexBuffer*/
11708 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
11709 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
11710 if(!ib) {
11711 skip("Failed to create an index buffer\n");
11712 goto out;
11715 /* copy all Buffers (Vertex + Index)*/
11716 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
11717 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
11718 memcpy(data, quad, sizeof(quad));
11719 hr = IDirect3DVertexBuffer9_Unlock(vb);
11720 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
11721 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
11722 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
11723 memcpy(data, vertcolor, sizeof(vertcolor));
11724 hr = IDirect3DVertexBuffer9_Unlock(vb2);
11725 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
11726 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
11727 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
11728 memcpy(data, instancepos, sizeof(instancepos));
11729 hr = IDirect3DVertexBuffer9_Unlock(vb3);
11730 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
11731 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
11732 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
11733 memcpy(data, indices, sizeof(indices));
11734 hr = IDirect3DIndexBuffer9_Unlock(ib);
11735 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
11737 /* create VertexShader */
11738 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
11739 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
11740 if(!shader) {
11741 skip("Failed to create a vertex shader.\n");
11742 goto out;
11745 hr = IDirect3DDevice9_SetVertexShader(device, shader);
11746 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
11748 hr = IDirect3DDevice9_SetIndices(device, ib);
11749 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
11751 /* run all tests */
11752 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
11754 struct testdata act = testcases[i];
11755 decl[0].Stream = act.strVertex;
11756 decl[1].Stream = act.strColor;
11757 decl[2].Stream = act.strInstance;
11758 /* create VertexDeclarations */
11759 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
11760 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
11762 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
11763 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
11765 hr = IDirect3DDevice9_BeginScene(device);
11766 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11768 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
11769 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
11771 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex,
11772 (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
11773 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11774 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
11775 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11777 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor,
11778 (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
11779 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11780 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
11781 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11783 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance,
11784 (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
11785 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11786 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
11787 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11789 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
11790 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11791 hr = IDirect3DDevice9_EndScene(device);
11792 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11794 /* set all StreamSource && StreamSourceFreq back to default */
11795 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
11796 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11797 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
11798 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11799 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
11800 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11801 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
11802 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11803 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
11804 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11805 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
11806 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11808 hr = IDirect3DVertexDeclaration9_Release(pDecl);
11809 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
11811 color = getPixelColor(device, 160, 360);
11812 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
11813 color = getPixelColor(device, 480, 360);
11814 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
11815 color = getPixelColor(device, 480, 120);
11816 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
11817 color = getPixelColor(device, 160, 120);
11818 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
11820 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11821 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
11824 out:
11825 if(vb) IDirect3DVertexBuffer9_Release(vb);
11826 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
11827 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
11828 if(ib)IDirect3DIndexBuffer9_Release(ib);
11829 if(shader)IDirect3DVertexShader9_Release(shader);
11830 refcount = IDirect3DDevice9_Release(device);
11831 ok(!refcount, "Device has %u references left.\n", refcount);
11832 done:
11833 IDirect3D9_Release(d3d);
11834 DestroyWindow(window);
11837 static void np2_stretch_rect_test(void)
11839 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
11840 IDirect3DTexture9 *dsttex = NULL;
11841 IDirect3DDevice9 *device;
11842 IDirect3D9 *d3d;
11843 D3DCOLOR color;
11844 ULONG refcount;
11845 HWND window;
11846 HRESULT hr;
11848 static const D3DRECT r1 = {0, 0, 50, 50 };
11849 static const D3DRECT r2 = {50, 0, 100, 50 };
11850 static const D3DRECT r3 = {50, 50, 100, 100};
11851 static const D3DRECT r4 = {0, 50, 50, 100};
11852 static const float quad[] =
11854 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
11855 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
11856 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
11857 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
11860 window = create_window();
11861 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11862 ok(!!d3d, "Failed to create a D3D object.\n");
11863 if (!(device = create_device(d3d, window, window, TRUE)))
11865 skip("Failed to create a D3D device, skipping tests.\n");
11866 goto done;
11869 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
11870 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
11872 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
11873 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
11874 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
11875 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
11877 if(!src || !dsttex) {
11878 skip("One or more test resources could not be created\n");
11879 goto cleanup;
11882 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
11883 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
11885 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
11886 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11888 /* Clear the StretchRect destination for debugging */
11889 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
11890 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
11891 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
11892 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11894 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
11895 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
11897 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
11898 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11899 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
11900 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11901 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
11902 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11903 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
11904 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11906 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
11907 * the target -> texture GL blit path
11909 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
11910 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
11911 IDirect3DSurface9_Release(dst);
11913 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11914 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
11916 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
11917 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
11918 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11919 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
11920 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11921 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
11922 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
11923 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
11925 hr = IDirect3DDevice9_BeginScene(device);
11926 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11927 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
11928 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11929 hr = IDirect3DDevice9_EndScene(device);
11930 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11932 color = getPixelColor(device, 160, 360);
11933 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
11934 color = getPixelColor(device, 480, 360);
11935 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
11936 color = getPixelColor(device, 480, 120);
11937 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
11938 color = getPixelColor(device, 160, 120);
11939 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
11940 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11941 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
11943 cleanup:
11944 if(src) IDirect3DSurface9_Release(src);
11945 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
11946 if(dsttex) IDirect3DTexture9_Release(dsttex);
11947 refcount = IDirect3DDevice9_Release(device);
11948 ok(!refcount, "Device has %u references left.\n", refcount);
11949 done:
11950 IDirect3D9_Release(d3d);
11951 DestroyWindow(window);
11954 static void texop_test(void)
11956 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
11957 IDirect3DTexture9 *texture = NULL;
11958 D3DLOCKED_RECT locked_rect;
11959 IDirect3DDevice9 *device;
11960 IDirect3D9 *d3d;
11961 D3DCOLOR color;
11962 ULONG refcount;
11963 D3DCAPS9 caps;
11964 HWND window;
11965 HRESULT hr;
11966 unsigned i;
11968 static const struct {
11969 float x, y, z;
11970 float s, t;
11971 D3DCOLOR diffuse;
11972 } quad[] = {
11973 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
11974 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
11975 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
11976 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
11979 static const D3DVERTEXELEMENT9 decl_elements[] = {
11980 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
11981 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
11982 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
11983 D3DDECL_END()
11986 static const struct {
11987 D3DTEXTUREOP op;
11988 const char *name;
11989 DWORD caps_flag;
11990 D3DCOLOR result;
11991 } test_data[] = {
11992 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
11993 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
11994 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
11995 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
11996 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
11997 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
11998 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
11999 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
12000 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
12001 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
12002 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
12003 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
12004 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
12005 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
12006 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
12007 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
12008 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
12009 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
12010 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
12011 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
12012 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT3", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
12013 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
12014 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
12017 window = create_window();
12018 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12019 ok(!!d3d, "Failed to create a D3D object.\n");
12020 if (!(device = create_device(d3d, window, window, TRUE)))
12022 skip("Failed to create a D3D device, skipping tests.\n");
12023 goto done;
12026 memset(&caps, 0, sizeof(caps));
12027 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12028 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
12030 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
12031 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
12032 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
12033 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
12035 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
12036 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
12037 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
12038 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
12039 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
12040 hr = IDirect3DTexture9_UnlockRect(texture, 0);
12041 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
12042 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
12043 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
12045 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
12046 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12047 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12048 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12049 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12050 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12052 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
12053 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12055 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12056 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12057 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
12058 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12059 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
12060 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12062 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12063 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12065 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
12067 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
12069 skip("tex operation %s not supported\n", test_data[i].name);
12070 continue;
12073 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
12074 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
12076 hr = IDirect3DDevice9_BeginScene(device);
12077 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
12079 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12080 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
12082 hr = IDirect3DDevice9_EndScene(device);
12083 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
12085 color = getPixelColor(device, 320, 240);
12086 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
12087 test_data[i].name, color, test_data[i].result);
12089 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12090 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12093 IDirect3DTexture9_Release(texture);
12094 IDirect3DVertexDeclaration9_Release(vertex_declaration);
12095 refcount = IDirect3DDevice9_Release(device);
12096 ok(!refcount, "Device has %u references left.\n", refcount);
12097 done:
12098 IDirect3D9_Release(d3d);
12099 DestroyWindow(window);
12102 static void yuv_color_test(void)
12104 HRESULT hr;
12105 IDirect3DSurface9 *surface, *target;
12106 unsigned int i;
12107 D3DLOCKED_RECT lr;
12108 IDirect3D9 *d3d;
12109 D3DCOLOR color;
12110 D3DFORMAT skip_once = D3DFMT_UNKNOWN;
12111 IDirect3DDevice9 *device;
12112 D3DSURFACE_DESC desc;
12113 ULONG refcount;
12114 HWND window;
12116 static const struct
12118 DWORD in;
12119 D3DFORMAT format;
12120 const char *fmt_string;
12121 D3DCOLOR left, right;
12123 test_data[] =
12125 {0x00000000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00008700, 0x00008700},
12126 {0xff000000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00008700, 0x004bff1c},
12127 {0x00ff0000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b30000, 0x00b30000},
12128 {0x0000ff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bff1c, 0x00008700},
12129 {0x000000ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000030e1, 0x000030e1},
12130 {0xffff0000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b30000, 0x00ffd01c},
12131 {0xff00ff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bff1c, 0x004bff1c},
12132 {0xff0000ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000030e1, 0x004bffff},
12133 {0x00ffff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffd01c, 0x00b30000},
12134 {0x00ff00ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b300e1, 0x00b300e1},
12135 {0x0000ffff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bffff, 0x001030e1},
12136 {0xffffff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffd01c, 0x00ffd01c},
12137 {0xffff00ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b300e1, 0x00ff79ff},
12138 {0xffffffff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ff79ff, 0x00ff79ff},
12139 {0x4cff4c54, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ff0000, 0x00ff0000},
12140 {0x00800080, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00000000, 0x00000000},
12141 {0xff80ff80, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffffff, 0x00ffffff},
12142 {0x1c6b1cff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000000fd, 0x000000fd},
12144 {0x00000000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00008700, 0x00008700},
12145 {0xff000000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b30000, 0x00b30000},
12146 {0x00ff0000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00008700, 0x004bff1c},
12147 {0x0000ff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000030e1, 0x000030e1},
12148 {0x000000ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bff1c, 0x00008700},
12149 {0xffff0000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b30000, 0x00ffd01c},
12150 {0xff00ff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b300e1, 0x00b300e1},
12151 {0xff0000ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ffd01c, 0x00b30000},
12152 {0x00ffff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000030e1, 0x004bffff},
12153 {0x00ff00ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bff1c, 0x004bff1c},
12154 {0x0000ffff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bffff, 0x000030e1},
12155 {0xffffff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b300e1, 0x00ff79ff},
12156 {0xffff00ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ffd01c, 0x00ffd01c},
12157 {0xffffffff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ff79ff, 0x00ff79ff},
12158 {0x4cff4c54, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000b8b00, 0x00b6ffa3},
12159 {0x00800080, D3DFMT_YUY2, "D3DFMT_YUY2", 0x0000ff00, 0x0000ff00},
12160 {0xff80ff80, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ff00ff, 0x00ff00ff},
12161 {0x1c6b1cff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x006dff45, 0x0000d500},
12164 window = create_window();
12165 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12166 ok(!!d3d, "Failed to create a D3D object.\n");
12167 if (!(device = create_device(d3d, window, window, TRUE)))
12169 skip("Failed to create a D3D device, skipping tests.\n");
12170 goto done;
12173 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
12174 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
12175 hr = IDirect3DSurface9_GetDesc(target, &desc);
12176 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
12178 for (i = 0; i < sizeof(test_data) / sizeof(test_data[0]); i++)
12180 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect.
12181 * Thus use StretchRect to draw the YUV surface onto the screen instead of drawPrimitive. */
12182 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
12183 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, test_data[i].format)))
12185 if (skip_once != test_data[i].format)
12187 skip("%s is not supported.\n", test_data[i].fmt_string);
12188 skip_once = test_data[i].format;
12190 continue;
12192 if (FAILED(IDirect3D9_CheckDeviceFormatConversion(d3d, 0,
12193 D3DDEVTYPE_HAL, test_data[i].format, desc.Format)))
12195 if (skip_once != test_data[i].format)
12197 skip("Driver cannot blit %s surfaces.\n", test_data[i].fmt_string);
12198 skip_once = test_data[i].format;
12200 continue;
12203 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1.
12204 * However, Nvidia Windows drivers have problems with 2x1 YUY2/UYVY surfaces, so use a 4x1 surface and
12205 * fill the second block with dummy data. If the surface has a size of 2x1, those drivers ignore the
12206 * second luminance value, resulting in an incorrect color in the right pixel. */
12207 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 1, test_data[i].format,
12208 D3DPOOL_DEFAULT, &surface, NULL);
12209 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
12212 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
12213 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
12214 ((DWORD *)lr.pBits)[0] = test_data[i].in;
12215 ((DWORD *)lr.pBits)[1] = 0x00800080;
12216 hr = IDirect3DSurface9_UnlockRect(surface);
12217 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
12219 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
12220 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
12221 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
12222 ok(SUCCEEDED(hr), "Failed to draw surface onto backbuffer, hr %#x.\n", hr);
12224 /* Some Windows drivers (mostly Nvidia, but also some VM drivers) insist on doing linear filtering
12225 * although we asked for point filtering. Be careful when reading the results and use the pixel
12226 * centers. In the future we may want to add tests for the filtered pixels as well.
12228 * Unfortunately different implementations(Windows-Nvidia and Mac-AMD tested) interpret some colors
12229 * vastly differently, so we need a max diff of 18. */
12230 color = getPixelColor(device, 1, 240);
12231 ok(color_match(color, test_data[i].left, 18),
12232 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s.\n",
12233 test_data[i].in, color, test_data[i].left, test_data[i].fmt_string);
12234 color = getPixelColor(device, 318, 240);
12235 ok(color_match(color, test_data[i].right, 18),
12236 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s.\n",
12237 test_data[i].in, color, test_data[i].right, test_data[i].fmt_string);
12238 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12239 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
12240 IDirect3DSurface9_Release(surface);
12243 IDirect3DSurface9_Release(target);
12244 refcount = IDirect3DDevice9_Release(device);
12245 ok(!refcount, "Device has %u references left.\n", refcount);
12246 done:
12247 IDirect3D9_Release(d3d);
12248 DestroyWindow(window);
12251 static void yuv_layout_test(void)
12253 HRESULT hr;
12254 IDirect3DSurface9 *surface, *target;
12255 unsigned int fmt, i, x, y;
12256 D3DFORMAT format;
12257 const char *fmt_string;
12258 D3DLOCKED_RECT lr;
12259 IDirect3D9 *d3d;
12260 D3DCOLOR color;
12261 DWORD ref_color;
12262 BYTE *buf, *chroma_buf, *u_buf, *v_buf;
12263 UINT width = 20, height = 16;
12264 IDirect3DDevice9 *device;
12265 ULONG refcount;
12266 D3DCAPS9 caps;
12267 D3DSURFACE_DESC desc;
12268 HWND window;
12270 static const struct
12272 DWORD color1, color2;
12273 DWORD rgb1, rgb2;
12275 test_data[] =
12277 { 0x000000, 0xffffff, 0x00008800, 0x00ff7dff },
12278 { 0xff0000, 0x00ffff, 0x004aff14, 0x00b800ee },
12279 { 0x00ff00, 0xff00ff, 0x000024ee, 0x00ffe114 },
12280 { 0x0000ff, 0xffff00, 0x00b80000, 0x004affff },
12281 { 0xffff00, 0x0000ff, 0x004affff, 0x00b80000 },
12282 { 0xff00ff, 0x00ff00, 0x00ffe114, 0x000024ee },
12283 { 0x00ffff, 0xff0000, 0x00b800ee, 0x004aff14 },
12284 { 0xffffff, 0x000000, 0x00ff7dff, 0x00008800 },
12287 static const struct
12289 D3DFORMAT format;
12290 const char *str;
12292 formats[] =
12294 { D3DFMT_UYVY, "D3DFMT_UYVY", },
12295 { D3DFMT_YUY2, "D3DFMT_YUY2", },
12296 { MAKEFOURCC('Y','V','1','2'), "D3DFMT_YV12", },
12297 { MAKEFOURCC('N','V','1','2'), "D3DFMT_NV12", },
12300 window = create_window();
12301 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12302 ok(!!d3d, "Failed to create a D3D object.\n");
12303 if (!(device = create_device(d3d, window, window, TRUE)))
12305 skip("Failed to create a D3D device, skipping tests.\n");
12306 goto done;
12309 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12310 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
12311 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2
12312 && !(caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL))
12314 skip("No NP2 texture support, skipping YUV texture layout test.\n");
12315 IDirect3DDevice9_Release(device);
12316 goto done;
12319 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
12320 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %#x.\n", hr);
12321 hr = IDirect3DSurface9_GetDesc(target, &desc);
12322 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
12324 for (fmt = 0; fmt < sizeof(formats) / sizeof(formats[0]); fmt++)
12326 format = formats[fmt].format;
12327 fmt_string = formats[fmt].str;
12329 /* Some (all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in
12330 * StretchRect. Thus use StretchRect to draw the YUV surface onto the screen instead
12331 * of drawPrimitive. */
12332 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
12333 D3DRTYPE_SURFACE, format) != D3D_OK)
12335 skip("%s is not supported.\n", fmt_string);
12336 continue;
12338 if (FAILED(IDirect3D9_CheckDeviceFormatConversion(d3d, 0,
12339 D3DDEVTYPE_HAL, format, desc.Format)))
12341 skip("Driver cannot blit %s surfaces.\n", fmt_string);
12342 continue;
12345 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, width, height, format, D3DPOOL_DEFAULT, &surface, NULL);
12346 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %#x.\n", hr);
12348 for (i = 0; i < sizeof(test_data) / sizeof(test_data[0]); i++)
12350 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
12351 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %#x.\n", hr);
12352 buf = lr.pBits;
12353 chroma_buf = buf + lr.Pitch * height;
12354 if (format == MAKEFOURCC('Y','V','1','2'))
12356 v_buf = chroma_buf;
12357 u_buf = chroma_buf + height / 2 * lr.Pitch/2;
12359 /* Draw the top left quarter of the screen with color1, the rest with color2 */
12360 for (y = 0; y < height; y++)
12362 for (x = 0; x < width; x += 2)
12364 DWORD color = (x < width / 2 && y < height / 2) ? test_data[i].color1 : test_data[i].color2;
12365 BYTE Y = (color >> 16) & 0xff;
12366 BYTE U = (color >> 8) & 0xff;
12367 BYTE V = (color >> 0) & 0xff;
12368 if (format == D3DFMT_UYVY)
12370 buf[y * lr.Pitch + 2 * x + 0] = U;
12371 buf[y * lr.Pitch + 2 * x + 1] = Y;
12372 buf[y * lr.Pitch + 2 * x + 2] = V;
12373 buf[y * lr.Pitch + 2 * x + 3] = Y;
12375 else if (format == D3DFMT_YUY2)
12377 buf[y * lr.Pitch + 2 * x + 0] = Y;
12378 buf[y * lr.Pitch + 2 * x + 1] = U;
12379 buf[y * lr.Pitch + 2 * x + 2] = Y;
12380 buf[y * lr.Pitch + 2 * x + 3] = V;
12382 else if (format == MAKEFOURCC('Y','V','1','2'))
12384 buf[y * lr.Pitch + x + 0] = Y;
12385 buf[y * lr.Pitch + x + 1] = Y;
12386 u_buf[(y / 2) * (lr.Pitch / 2) + (x / 2)] = U;
12387 v_buf[(y / 2) * (lr.Pitch / 2) + (x / 2)] = V;
12389 else if (format == MAKEFOURCC('N','V','1','2'))
12391 buf[y * lr.Pitch + x + 0] = Y;
12392 buf[y * lr.Pitch + x + 1] = Y;
12393 chroma_buf[(y / 2) * lr.Pitch + 2 * (x / 2) + 0] = U;
12394 chroma_buf[(y / 2) * lr.Pitch + 2 * (x / 2) + 1] = V;
12398 hr = IDirect3DSurface9_UnlockRect(surface);
12399 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %#x.\n", hr);
12401 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
12402 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %#x.\n", hr);
12403 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
12404 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %#x.\n", hr);
12406 /* Some Windows drivers (mostly Nvidia, but also some VM drivers) insist on doing linear filtering
12407 * although we asked for point filtering. To prevent running into precision problems, read at points
12408 * with some margin within each quadrant.
12410 * Unfortunately different implementations(Windows-Nvidia and Mac-AMD tested) interpret some colors
12411 * vastly differently, so we need a max diff of 18. */
12412 for (y = 0; y < 4; y++)
12414 for (x = 0; x < 4; x++)
12416 UINT xcoord = (1 + 2 * x) * 640 / 8;
12417 UINT ycoord = (1 + 2 * y) * 480 / 8;
12418 ref_color = (y < 2 && x < 2) ? test_data[i].rgb1 : test_data[i].rgb2;
12419 color = getPixelColor(device, xcoord, ycoord);
12420 ok(color_match(color, ref_color, 18),
12421 "Format %s: Got color %#x for pixel (%d/%d)/(%d/%d), pixel %d %d, expected %#x.\n",
12422 fmt_string, color, x, 4, y, 4, xcoord, ycoord, ref_color);
12425 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12427 ok(SUCCEEDED(hr), "Present failed with %#x.\n", hr);
12429 IDirect3DSurface9_Release(surface);
12432 IDirect3DSurface9_Release(target);
12433 refcount = IDirect3DDevice9_Release(device);
12434 ok(!refcount, "Device has %u references left.\n", refcount);
12435 done:
12436 IDirect3D9_Release(d3d);
12437 DestroyWindow(window);
12440 static void texop_range_test(void)
12442 IDirect3DTexture9 *texture;
12443 D3DLOCKED_RECT locked_rect;
12444 IDirect3DDevice9 *device;
12445 IDirect3D9 *d3d;
12446 ULONG refcount;
12447 D3DCAPS9 caps;
12448 DWORD color;
12449 HWND window;
12450 HRESULT hr;
12452 static const struct
12454 float x, y, z;
12455 D3DCOLOR diffuse;
12457 quad[] =
12459 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
12460 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
12461 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
12462 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
12465 window = create_window();
12466 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12467 ok(!!d3d, "Failed to create a D3D object.\n");
12468 if (!(device = create_device(d3d, window, window, TRUE)))
12470 skip("Failed to create a D3D device, skipping tests.\n");
12471 goto done;
12474 /* We need ADD and SUBTRACT operations */
12475 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12476 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
12477 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD))
12479 skip("D3DTOP_ADD is not supported, skipping value range test.\n");
12480 IDirect3DDevice9_Release(device);
12481 goto done;
12483 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT))
12485 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test.\n");
12486 IDirect3DDevice9_Release(device);
12487 goto done;
12490 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12491 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
12492 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12493 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
12494 /* Stage 1: result = diffuse(=1.0) + diffuse
12495 * stage 2: result = result - tfactor(= 0.5)
12497 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12498 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12499 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
12500 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12501 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
12502 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12503 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
12504 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12505 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
12506 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12507 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12508 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12509 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
12510 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12512 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12513 ok(SUCCEEDED(hr), "Failed to clear device, hr %#x.\n\n", hr);
12514 hr = IDirect3DDevice9_BeginScene(device);
12515 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
12516 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12517 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
12518 hr = IDirect3DDevice9_EndScene(device);
12519 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
12521 color = getPixelColor(device, 320, 240);
12522 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
12523 color);
12524 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12525 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12527 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
12528 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
12529 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
12530 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
12531 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
12532 hr = IDirect3DTexture9_UnlockRect(texture, 0);
12533 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
12534 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
12535 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
12537 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
12538 * stage 2: result = result + diffuse(1.0)
12540 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12541 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12542 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12543 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12544 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12545 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12546 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
12547 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12548 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
12549 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12550 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
12551 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12552 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
12553 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12555 hr = IDirect3DDevice9_BeginScene(device);
12556 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
12557 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12558 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
12559 hr = IDirect3DDevice9_EndScene(device);
12560 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
12562 color = getPixelColor(device, 320, 240);
12563 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
12564 color);
12565 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12566 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12568 IDirect3DTexture9_Release(texture);
12569 refcount = IDirect3DDevice9_Release(device);
12570 ok(!refcount, "Device has %u references left.\n", refcount);
12571 done:
12572 IDirect3D9_Release(d3d);
12573 DestroyWindow(window);
12576 static void alphareplicate_test(void)
12578 IDirect3DDevice9 *device;
12579 IDirect3D9 *d3d;
12580 ULONG refcount;
12581 DWORD color;
12582 HWND window;
12583 HRESULT hr;
12585 static const struct
12587 struct vec3 position;
12588 DWORD diffuse;
12590 quad[] =
12592 {{-1.0f, -1.0f, 0.1f}, 0x80ff00ff},
12593 {{-1.0f, 1.0f, 0.1f}, 0x80ff00ff},
12594 {{ 1.0f, -1.0f, 0.1f}, 0x80ff00ff},
12595 {{ 1.0f, 1.0f, 0.1f}, 0x80ff00ff},
12598 window = create_window();
12599 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12600 ok(!!d3d, "Failed to create a D3D object.\n");
12601 if (!(device = create_device(d3d, window, window, TRUE)))
12603 skip("Failed to create a D3D device, skipping tests.\n");
12604 goto done;
12607 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12608 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12610 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12611 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12613 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12614 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12615 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
12616 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12618 hr = IDirect3DDevice9_BeginScene(device);
12619 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12620 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12621 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12622 hr = IDirect3DDevice9_EndScene(device);
12623 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12625 color = getPixelColor(device, 320, 240);
12626 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
12627 color);
12628 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12629 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12631 refcount = IDirect3DDevice9_Release(device);
12632 ok(!refcount, "Device has %u references left.\n", refcount);
12633 done:
12634 IDirect3D9_Release(d3d);
12635 DestroyWindow(window);
12638 static void dp3_alpha_test(void)
12640 IDirect3DDevice9 *device;
12641 IDirect3D9 *d3d;
12642 ULONG refcount;
12643 D3DCAPS9 caps;
12644 DWORD color;
12645 HWND window;
12646 HRESULT hr;
12648 static const struct
12650 struct vec3 position;
12651 DWORD diffuse;
12653 quad[] =
12655 {{-1.0f, -1.0f, 0.1f}, 0x408080c0},
12656 {{-1.0f, 1.0f, 0.1f}, 0x408080c0},
12657 {{ 1.0f, -1.0f, 0.1f}, 0x408080c0},
12658 {{ 1.0f, 1.0f, 0.1f}, 0x408080c0},
12661 window = create_window();
12662 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12663 ok(!!d3d, "Failed to create a D3D object.\n");
12664 if (!(device = create_device(d3d, window, window, TRUE)))
12666 skip("Failed to create a D3D device, skipping tests.\n");
12667 goto done;
12670 memset(&caps, 0, sizeof(caps));
12671 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12672 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
12673 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3))
12675 skip("D3DTOP_DOTPRODUCT3 not supported\n");
12676 IDirect3DDevice9_Release(device);
12677 goto done;
12680 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12681 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12683 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12684 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12686 /* dp3_x4 r0, diffuse_bias, tfactor_bias
12687 * mov r0.a, diffuse.a
12688 * mov r0, r0.a
12690 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
12691 * 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
12692 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
12694 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
12695 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12696 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
12697 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12698 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12699 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12700 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
12701 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12702 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
12703 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12704 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12705 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12706 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
12707 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12708 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
12709 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12710 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
12711 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12712 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12713 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
12715 hr = IDirect3DDevice9_BeginScene(device);
12716 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12717 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12718 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12719 hr = IDirect3DDevice9_EndScene(device);
12720 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12722 color = getPixelColor(device, 320, 240);
12723 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
12724 color);
12725 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12726 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12728 refcount = IDirect3DDevice9_Release(device);
12729 ok(!refcount, "Device has %u references left.\n", refcount);
12730 done:
12731 IDirect3D9_Release(d3d);
12732 DestroyWindow(window);
12735 static void zwriteenable_test(void)
12737 IDirect3DDevice9 *device;
12738 IDirect3D9 *d3d;
12739 D3DCOLOR color;
12740 ULONG refcount;
12741 HWND window;
12742 HRESULT hr;
12744 static const struct
12746 struct vec3 position;
12747 DWORD diffuse;
12749 quad1[] =
12751 {{-1.0f, -1.0f, 0.1f}, 0x00ff0000},
12752 {{-1.0f, 1.0f, 0.1f}, 0x00ff0000},
12753 {{ 1.0f, -1.0f, 0.1f}, 0x00ff0000},
12754 {{ 1.0f, 1.0f, 0.1f}, 0x00ff0000},
12756 quad2[] =
12758 {{-1.0f, -1.0f, 0.9f}, 0x0000ff00},
12759 {{-1.0f, 1.0f, 0.9f}, 0x0000ff00},
12760 {{ 1.0f, -1.0f, 0.9f}, 0x0000ff00},
12761 {{ 1.0f, 1.0f, 0.9f}, 0x0000ff00},
12764 window = create_window();
12765 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12766 ok(!!d3d, "Failed to create a D3D object.\n");
12767 if (!(device = create_device(d3d, window, window, TRUE)))
12769 skip("Failed to create a D3D device, skipping tests.\n");
12770 goto done;
12773 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
12774 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12776 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12777 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12778 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12779 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12780 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12781 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12782 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
12783 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12784 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12785 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
12787 hr = IDirect3DDevice9_BeginScene(device);
12788 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12789 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1,
12790 * zenable = D3DZB_FALSE, zwriteenable = TRUE. The red color is written
12791 * because the z test is disabled. The question is whether the z = 0.1
12792 * values are written into the Z buffer. After the draw, set
12793 * zenable = TRUE and draw a green quad at z = 0.9. If the values are
12794 * written, the z test will fail(0.9 > 0.1) and the red color remains. If
12795 * the values are not written, the z test succeeds(0.9 < 1.0) and the
12796 * green color is written. It turns out that the screen is green, so
12797 * zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z
12798 * buffer. */
12799 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
12800 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12801 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12802 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
12803 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
12804 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12805 hr = IDirect3DDevice9_EndScene(device);
12806 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12808 color = getPixelColor(device, 320, 240);
12809 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
12810 color);
12811 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12812 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12814 refcount = IDirect3DDevice9_Release(device);
12815 ok(!refcount, "Device has %u references left.\n", refcount);
12816 done:
12817 IDirect3D9_Release(d3d);
12818 DestroyWindow(window);
12821 static void alphatest_test(void)
12823 #define ALPHATEST_PASSED 0x0000ff00
12824 #define ALPHATEST_FAILED 0x00ff0000
12825 IDirect3DDevice9 *device;
12826 unsigned int i, j;
12827 IDirect3D9 *d3d;
12828 D3DCOLOR color;
12829 ULONG refcount;
12830 D3DCAPS9 caps;
12831 HWND window;
12832 HRESULT hr;
12834 static const struct
12836 D3DCMPFUNC func;
12837 D3DCOLOR color_less;
12838 D3DCOLOR color_equal;
12839 D3DCOLOR color_greater;
12841 testdata[] =
12843 {D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED},
12844 {D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED},
12845 {D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED},
12846 {D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED},
12847 {D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED},
12848 {D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED},
12849 {D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED},
12850 {D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED},
12852 static const struct
12854 struct vec3 position;
12855 DWORD diffuse;
12857 quad[] =
12859 {{-1.0f, -1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
12860 {{-1.0f, 1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
12861 {{ 1.0f, -1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
12862 {{ 1.0f, 1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
12865 window = create_window();
12866 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12867 ok(!!d3d, "Failed to create a D3D object.\n");
12868 if (!(device = create_device(d3d, window, window, TRUE)))
12870 skip("Failed to create a D3D device, skipping tests.\n");
12871 goto done;
12874 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
12875 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
12877 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12878 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
12879 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
12880 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12881 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12882 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12884 for (j = 0; j < 2; ++j)
12886 if (j == 1)
12888 /* Try a pixel shader instead of fixed function. The wined3d code
12889 * may emulate the alpha test either for performance reasons
12890 * (floating point RTs) or to work around driver bugs (GeForce
12891 * 7x00 cards on MacOS). There may be a different codepath for ffp
12892 * and shader in this case, and the test should cover both. */
12893 IDirect3DPixelShader9 *ps;
12894 static const DWORD shader_code[] =
12896 0xffff0101, /* ps_1_1 */
12897 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
12898 0x0000ffff /* end */
12900 memset(&caps, 0, sizeof(caps));
12901 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12902 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
12903 if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
12904 break;
12907 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
12908 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
12909 hr = IDirect3DDevice9_SetPixelShader(device, ps);
12910 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
12911 IDirect3DPixelShader9_Release(ps);
12914 for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
12915 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
12916 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12918 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
12919 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12920 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
12921 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12922 hr = IDirect3DDevice9_BeginScene(device);
12923 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12924 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12925 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12926 hr = IDirect3DDevice9_EndScene(device);
12927 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12928 color = getPixelColor(device, 320, 240);
12929 ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
12930 color, testdata[i].color_less, testdata[i].func);
12931 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12932 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12934 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
12935 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12936 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
12937 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12938 hr = IDirect3DDevice9_BeginScene(device);
12939 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12940 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12941 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12942 hr = IDirect3DDevice9_EndScene(device);
12943 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12944 color = getPixelColor(device, 320, 240);
12945 ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
12946 color, testdata[i].color_equal, testdata[i].func);
12947 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12948 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12950 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
12951 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12952 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
12953 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12954 hr = IDirect3DDevice9_BeginScene(device);
12955 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12956 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12957 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12958 hr = IDirect3DDevice9_EndScene(device);
12959 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12960 color = getPixelColor(device, 320, 240);
12961 ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
12962 color, testdata[i].color_greater, testdata[i].func);
12963 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12964 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12968 refcount = IDirect3DDevice9_Release(device);
12969 ok(!refcount, "Device has %u references left.\n", refcount);
12970 done:
12971 IDirect3D9_Release(d3d);
12972 DestroyWindow(window);
12975 static void sincos_test(void)
12977 IDirect3DVertexShader9 *sin_shader, *cos_shader;
12978 IDirect3DDevice9 *device;
12979 struct vec3 data[1280];
12980 IDirect3D9 *d3d;
12981 unsigned int i;
12982 ULONG refcount;
12983 D3DCAPS9 caps;
12984 HWND window;
12985 HRESULT hr;
12987 static const DWORD sin_shader_code[] =
12989 0xfffe0200, /* vs_2_0 */
12990 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
12991 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
12992 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
12993 0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.y, r1.x, c0, c1 */
12994 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
12995 0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002, /* mul oPos.y, r0.y, c2.w */
12996 0x02000001, 0xd00f0000, 0xa0a60002, /* mov oD0, c2.zyzz */
12997 0x0000ffff /* end */
12999 static const DWORD cos_shader_code[] =
13001 0xfffe0200, /* vs_2_0 */
13002 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
13003 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
13004 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
13005 0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.x, r1.x, c0, c1 */
13006 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
13007 0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002, /* mul oPos.y, r0.x, c2.w */
13008 0x02000001, 0xd00f0000, 0xa0a90002, /* mov oD0, c2.yzzz */
13009 0x0000ffff /* end */
13011 static const float sincosc1[4] = {D3DSINCOSCONST1};
13012 static const float sincosc2[4] = {D3DSINCOSCONST2};
13014 window = create_window();
13015 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13016 ok(!!d3d, "Failed to create a D3D object.\n");
13017 if (!(device = create_device(d3d, window, window, TRUE)))
13019 skip("Failed to create a D3D device, skipping tests.\n");
13020 goto done;
13023 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13024 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13025 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
13027 skip("No vs_2_0 support, skipping tests.\n");
13028 IDirect3DDevice9_Release(device);
13029 goto done;
13032 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
13033 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
13035 hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
13036 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
13037 hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
13038 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
13039 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13040 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
13041 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
13042 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
13043 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
13044 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
13046 /* Generate a point from -1 to 1 every 0.5 pixels */
13047 for(i = 0; i < 1280; i++) {
13048 data[i].x = (-640.0 + i) / 640.0;
13049 data[i].y = 0.0;
13050 data[i].z = 0.1;
13053 hr = IDirect3DDevice9_BeginScene(device);
13054 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13056 hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
13057 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
13058 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
13059 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13061 hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
13062 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
13063 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
13064 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13066 hr = IDirect3DDevice9_EndScene(device);
13067 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13069 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13070 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
13071 /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
13073 IDirect3DVertexShader9_Release(sin_shader);
13074 IDirect3DVertexShader9_Release(cos_shader);
13075 refcount = IDirect3DDevice9_Release(device);
13076 ok(!refcount, "Device has %u references left.\n", refcount);
13077 done:
13078 IDirect3D9_Release(d3d);
13079 DestroyWindow(window);
13082 static void loop_index_test(void)
13084 IDirect3DVertexShader9 *shader;
13085 IDirect3DDevice9 *device;
13086 IDirect3D9 *d3d;
13087 float values[4];
13088 ULONG refcount;
13089 D3DCAPS9 caps;
13090 DWORD color;
13091 HWND window;
13092 HRESULT hr;
13094 static const DWORD shader_code[] =
13096 0xfffe0200, /* vs_2_0 */
13097 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
13098 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
13099 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
13100 0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1] */
13101 0x0000001d, /* endloop */
13102 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
13103 0x02000001, 0xd00f0000, 0x80e40000, /* mov oD0, r0 */
13104 0x0000ffff /* END */
13106 static const float quad[] =
13108 -1.0f, -1.0f, 0.1f,
13109 -1.0f, 1.0f, 0.1f,
13110 1.0f, -1.0f, 0.1f,
13111 1.0f, 1.0f, 0.1f,
13113 static const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
13114 static const float one[4] = {1.0f, 1.0f, 1.0f, 1.0f};
13115 static const int i0[4] = {2, 10, -3, 0};
13117 window = create_window();
13118 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13119 ok(!!d3d, "Failed to create a D3D object.\n");
13120 if (!(device = create_device(d3d, window, window, TRUE)))
13122 skip("Failed to create a D3D device, skipping tests.\n");
13123 goto done;
13126 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13127 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13128 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
13130 skip("No vs_2_0 support, skipping tests.\n");
13131 IDirect3DDevice9_Release(device);
13132 goto done;
13135 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
13136 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
13137 hr = IDirect3DDevice9_SetVertexShader(device, shader);
13138 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
13139 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13140 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
13141 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
13142 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
13144 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
13145 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13146 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
13147 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13148 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
13149 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13150 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
13151 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13152 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
13153 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13154 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
13155 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13156 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
13157 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13158 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
13159 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13160 values[0] = 1.0;
13161 values[1] = 1.0;
13162 values[2] = 0.0;
13163 values[3] = 0.0;
13164 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
13165 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13166 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
13167 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13168 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
13169 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13170 values[0] = -1.0;
13171 values[1] = 0.0;
13172 values[2] = 0.0;
13173 values[3] = 0.0;
13174 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
13175 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13176 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
13177 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13178 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
13179 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13180 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
13181 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13182 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
13183 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13185 hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
13186 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
13188 hr = IDirect3DDevice9_BeginScene(device);
13189 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13190 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
13191 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13192 hr = IDirect3DDevice9_EndScene(device);
13193 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13194 color = getPixelColor(device, 320, 240);
13195 ok(color_match(color, 0x0000ff00, 1),
13196 "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
13197 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13198 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
13200 IDirect3DVertexShader9_Release(shader);
13201 refcount = IDirect3DDevice9_Release(device);
13202 ok(!refcount, "Device has %u references left.\n", refcount);
13203 done:
13204 IDirect3D9_Release(d3d);
13205 DestroyWindow(window);
13208 static void sgn_test(void)
13210 IDirect3DVertexShader9 *shader;
13211 IDirect3DDevice9 *device;
13212 IDirect3D9 *d3d;
13213 ULONG refcount;
13214 D3DCAPS9 caps;
13215 DWORD color;
13216 HWND window;
13217 HRESULT hr;
13219 static const DWORD shader_code[] =
13221 0xfffe0200, /* vs_2_0 */
13222 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position o0 */
13223 0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
13224 0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0 */
13225 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
13226 0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002, /* sgn r0, c0, r1, r2 */
13227 0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001, /* add oD0, r0, c1 */
13228 0x0000ffff /* end */
13230 static const float quad[] =
13232 -1.0f, -1.0f, 0.1f,
13233 -1.0f, 1.0f, 0.1f,
13234 1.0f, -1.0f, 0.1f,
13235 1.0f, 1.0f, 0.1f,
13238 window = create_window();
13239 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13240 ok(!!d3d, "Failed to create a D3D object.\n");
13241 if (!(device = create_device(d3d, window, window, TRUE)))
13243 skip("Failed to create a D3D device, skipping tests.\n");
13244 goto done;
13247 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13248 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13249 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
13251 skip("No vs_2_0 support, skipping tests.\n");
13252 IDirect3DDevice9_Release(device);
13253 goto done;
13256 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
13257 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
13258 hr = IDirect3DDevice9_SetVertexShader(device, shader);
13259 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
13260 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13261 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
13262 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
13263 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
13265 hr = IDirect3DDevice9_BeginScene(device);
13266 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13267 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
13268 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13269 hr = IDirect3DDevice9_EndScene(device);
13270 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13271 color = getPixelColor(device, 320, 240);
13272 ok(color_match(color, 0x008000ff, 1),
13273 "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
13274 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13275 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
13277 IDirect3DVertexShader9_Release(shader);
13278 refcount = IDirect3DDevice9_Release(device);
13279 ok(!refcount, "Device has %u references left.\n", refcount);
13280 done:
13281 IDirect3D9_Release(d3d);
13282 DestroyWindow(window);
13285 static void viewport_test(void)
13287 IDirect3DDevice9 *device;
13288 BOOL draw_failed = TRUE;
13289 D3DVIEWPORT9 vp;
13290 IDirect3D9 *d3d;
13291 ULONG refcount;
13292 DWORD color;
13293 HWND window;
13294 HRESULT hr;
13296 static const float quad[] =
13298 -0.5f, -0.5f, 0.1f,
13299 -0.5f, 0.5f, 0.1f,
13300 0.5f, -0.5f, 0.1f,
13301 0.5f, 0.5f, 0.1f,
13304 window = create_window();
13305 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13306 ok(!!d3d, "Failed to create a D3D object.\n");
13307 if (!(device = create_device(d3d, window, window, TRUE)))
13309 skip("Failed to create a D3D device, skipping tests.\n");
13310 goto done;
13313 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
13314 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
13316 /* Test a viewport with Width and Height bigger than the surface dimensions
13318 * TODO: Test Width < surface.width, but X + Width > surface.width
13319 * TODO: Test Width < surface.width, what happens with the height?
13321 * The expected behavior is that the viewport behaves like the "default"
13322 * viewport with X = Y = 0, Width = surface_width, Height = surface_height,
13323 * MinZ = 0.0, MaxZ = 1.0.
13325 * Starting with Windows 7 the behavior among driver versions is not
13326 * consistent. The SetViewport call is accepted on all drivers. Some
13327 * drivers(older nvidia ones) refuse to draw and return an error. Newer
13328 * nvidia drivers draw, but use the actual values in the viewport and only
13329 * display the upper left part on the surface.
13331 memset(&vp, 0, sizeof(vp));
13332 vp.X = 0;
13333 vp.Y = 0;
13334 vp.Width = 10000;
13335 vp.Height = 10000;
13336 vp.MinZ = 0.0;
13337 vp.MaxZ = 0.0;
13338 hr = IDirect3DDevice9_SetViewport(device, &vp);
13339 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
13341 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13342 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
13344 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13345 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
13346 hr = IDirect3DDevice9_BeginScene(device);
13347 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13348 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
13349 ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
13350 draw_failed = FAILED(hr);
13351 hr = IDirect3DDevice9_EndScene(device);
13352 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13354 if(!draw_failed)
13356 color = getPixelColor(device, 158, 118);
13357 ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
13358 color = getPixelColor(device, 162, 118);
13359 ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
13360 color = getPixelColor(device, 158, 122);
13361 ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
13362 color = getPixelColor(device, 162, 122);
13363 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (162,122) has color %08x\n", color);
13365 color = getPixelColor(device, 478, 358);
13366 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (478,358 has color %08x\n", color);
13367 color = getPixelColor(device, 482, 358);
13368 ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
13369 color = getPixelColor(device, 478, 362);
13370 ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
13371 color = getPixelColor(device, 482, 362);
13372 ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
13375 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13376 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
13378 refcount = IDirect3DDevice9_Release(device);
13379 ok(!refcount, "Device has %u references left.\n", refcount);
13380 done:
13381 IDirect3D9_Release(d3d);
13382 DestroyWindow(window);
13385 /* This test tests depth clamping / clipping behaviour:
13386 * - With software vertex processing, depth values are clamped to the
13387 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
13388 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
13389 * same as regular vertices here.
13390 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
13391 * Normal vertices are always clipped. Pretransformed vertices are
13392 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
13393 * - The viewport's MinZ/MaxZ is irrelevant for this.
13395 static void depth_clamp_test(void)
13397 IDirect3DDevice9 *device;
13398 D3DVIEWPORT9 vp;
13399 IDirect3D9 *d3d;
13400 D3DCOLOR color;
13401 ULONG refcount;
13402 D3DCAPS9 caps;
13403 HWND window;
13404 HRESULT hr;
13406 static const struct
13408 struct vec4 position;
13409 DWORD diffuse;
13411 quad1[] =
13413 {{ 0.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
13414 {{640.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
13415 {{ 0.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
13416 {{640.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
13418 quad2[] =
13420 {{ 0.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
13421 {{640.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
13422 {{ 0.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
13423 {{640.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
13425 quad3[] =
13427 {{112.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
13428 {{208.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
13429 {{112.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
13430 {{208.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
13432 quad4[] =
13434 {{ 42.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
13435 {{112.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
13436 {{ 42.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
13437 {{112.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
13439 static const struct
13441 struct vec3 position;
13442 DWORD diffuse;
13444 quad5[] =
13446 {{-0.5f, 0.5f, 10.0f}, 0xff14f914},
13447 {{ 0.5f, 0.5f, 10.0f}, 0xff14f914},
13448 {{-0.5f, -0.5f, 10.0f}, 0xff14f914},
13449 {{ 0.5f, -0.5f, 10.0f}, 0xff14f914},
13451 quad6[] =
13453 {{-1.0f, 0.5f, 10.0f}, 0xfff91414},
13454 {{ 1.0f, 0.5f, 10.0f}, 0xfff91414},
13455 {{-1.0f, 0.25f, 10.0f}, 0xfff91414},
13456 {{ 1.0f, 0.25f, 10.0f}, 0xfff91414},
13459 window = create_window();
13460 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13461 ok(!!d3d, "Failed to create a D3D object.\n");
13462 if (!(device = create_device(d3d, window, window, TRUE)))
13464 skip("Failed to create a D3D device, skipping tests.\n");
13465 goto done;
13468 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13469 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13471 vp.X = 0;
13472 vp.Y = 0;
13473 vp.Width = 640;
13474 vp.Height = 480;
13475 vp.MinZ = 0.0;
13476 vp.MaxZ = 7.5;
13478 hr = IDirect3DDevice9_SetViewport(device, &vp);
13479 if(FAILED(hr))
13481 /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
13482 * the tests because the 7.5 is just intended to show that it doesn't have
13483 * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
13484 * viewport and continue.
13486 ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
13487 vp.MaxZ = 1.0;
13488 hr = IDirect3DDevice9_SetViewport(device, &vp);
13490 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
13492 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
13493 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13495 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
13496 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13497 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13498 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13499 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13500 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13501 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13502 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13504 hr = IDirect3DDevice9_BeginScene(device);
13505 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13507 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
13508 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13510 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13511 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13512 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13513 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13515 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
13516 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13518 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
13519 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13520 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
13521 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13523 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
13524 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13526 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13527 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13529 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
13530 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13532 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
13533 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13535 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
13536 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13538 hr = IDirect3DDevice9_EndScene(device);
13539 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13541 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
13543 color = getPixelColor(device, 75, 75);
13544 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13545 color = getPixelColor(device, 150, 150);
13546 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13547 color = getPixelColor(device, 320, 240);
13548 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13549 color = getPixelColor(device, 320, 330);
13550 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13551 color = getPixelColor(device, 320, 330);
13552 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13554 else
13556 color = getPixelColor(device, 75, 75);
13557 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
13558 color = getPixelColor(device, 150, 150);
13559 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
13560 color = getPixelColor(device, 320, 240);
13561 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
13562 color = getPixelColor(device, 320, 330);
13563 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13564 color = getPixelColor(device, 320, 330);
13565 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13568 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13569 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13571 refcount = IDirect3DDevice9_Release(device);
13572 ok(!refcount, "Device has %u references left.\n", refcount);
13573 done:
13574 IDirect3D9_Release(d3d);
13575 DestroyWindow(window);
13578 static void depth_bounds_test(void)
13580 static const struct
13582 struct vec4 position;
13583 DWORD diffuse;
13585 quad1[] =
13587 {{ 0.0f, 0.0f, 0.0f, 1.0f}, 0xfff9e814},
13588 {{640.0f, 0.0f, 0.0f, 1.0f}, 0xfff9e814},
13589 {{ 0.0f, 480.0f, 1.0f, 1.0f}, 0xfff9e814},
13590 {{640.0f, 480.0f, 1.0f, 1.0f}, 0xfff9e814},
13592 quad2[] =
13594 {{ 0.0f, 0.0f, 0.6f, 1.0f}, 0xff002b7f},
13595 {{640.0f, 0.0f, 0.6f, 1.0f}, 0xff002b7f},
13596 {{ 0.0f, 480.0f, 0.6f, 1.0f}, 0xff002b7f},
13597 {{640.0f, 480.0f, 0.6f, 1.0f}, 0xff002b7f},
13599 quad3[] =
13601 {{ 0.0f, 100.0f, 0.6f, 1.0f}, 0xfff91414},
13602 {{640.0f, 100.0f, 0.6f, 1.0f}, 0xfff91414},
13603 {{ 0.0f, 160.0f, 0.6f, 1.0f}, 0xfff91414},
13604 {{640.0f, 160.0f, 0.6f, 1.0f}, 0xfff91414},
13607 union {
13608 DWORD d;
13609 float f;
13610 } tmpvalue;
13612 IDirect3DSurface9 *offscreen_surface = NULL;
13613 IDirect3DDevice9 *device;
13614 IDirect3D9 *d3d;
13615 D3DCOLOR color;
13616 ULONG refcount;
13617 HWND window;
13618 HRESULT hr;
13620 window = create_window();
13621 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13622 ok(!!d3d, "Failed to create a D3D object.\n");
13623 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
13624 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK)
13626 skip("No NVDB (depth bounds test) support, skipping tests.\n");
13627 goto done;
13629 if (!(device = create_device(d3d, window, window, TRUE)))
13631 skip("Failed to create a D3D device, skipping tests.\n");
13632 goto done;
13635 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
13636 MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
13637 ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
13638 if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
13640 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
13641 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13643 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13644 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13645 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13646 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13647 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13648 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13649 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13650 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13653 hr = IDirect3DDevice9_BeginScene(device);
13654 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13656 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
13657 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13659 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13660 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13662 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
13663 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13665 tmpvalue.f = 0.625;
13666 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
13667 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13669 tmpvalue.f = 0.75;
13670 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
13671 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13673 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13674 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13676 tmpvalue.f = 0.75;
13677 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
13678 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13680 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
13681 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13683 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
13684 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13686 hr = IDirect3DDevice9_EndScene(device);
13687 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13689 color = getPixelColor(device, 150, 130);
13690 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13691 color = getPixelColor(device, 150, 200);
13692 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13693 color = getPixelColor(device, 150, 300-5);
13694 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13695 color = getPixelColor(device, 150, 300+5);
13696 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
13697 color = getPixelColor(device, 150, 330);
13698 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
13699 color = getPixelColor(device, 150, 360-5);
13700 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
13701 color = getPixelColor(device, 150, 360+5);
13702 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13704 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13705 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13706 refcount = IDirect3DDevice9_Release(device);
13707 ok(!refcount, "Device has %u references left.\n", refcount);
13708 done:
13709 IDirect3D9_Release(d3d);
13710 DestroyWindow(window);
13713 static void depth_buffer_test(void)
13715 static const struct
13717 struct vec3 position;
13718 DWORD diffuse;
13720 quad1[] =
13722 {{-1.0, 1.0, 0.33f}, 0xff00ff00},
13723 {{ 1.0, 1.0, 0.33f}, 0xff00ff00},
13724 {{-1.0, -1.0, 0.33f}, 0xff00ff00},
13725 {{ 1.0, -1.0, 0.33f}, 0xff00ff00},
13727 quad2[] =
13729 {{-1.0, 1.0, 0.50f}, 0xffff00ff},
13730 {{ 1.0, 1.0, 0.50f}, 0xffff00ff},
13731 {{-1.0, -1.0, 0.50f}, 0xffff00ff},
13732 {{ 1.0, -1.0, 0.50f}, 0xffff00ff},
13734 quad3[] =
13736 {{-1.0, 1.0, 0.66f}, 0xffff0000},
13737 {{ 1.0, 1.0, 0.66f}, 0xffff0000},
13738 {{-1.0, -1.0, 0.66f}, 0xffff0000},
13739 {{ 1.0, -1.0, 0.66f}, 0xffff0000},
13741 static const DWORD expected_colors[4][4] =
13743 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
13744 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
13745 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
13746 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
13749 IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
13750 IDirect3DDevice9 *device;
13751 unsigned int i, j;
13752 D3DVIEWPORT9 vp;
13753 IDirect3D9 *d3d;
13754 D3DCOLOR color;
13755 ULONG refcount;
13756 HWND window;
13757 HRESULT hr;
13759 window = create_window();
13760 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13761 ok(!!d3d, "Failed to create a D3D object.\n");
13762 if (!(device = create_device(d3d, window, window, TRUE)))
13764 skip("Failed to create a D3D device, skipping tests.\n");
13765 goto done;
13768 vp.X = 0;
13769 vp.Y = 0;
13770 vp.Width = 640;
13771 vp.Height = 480;
13772 vp.MinZ = 0.0;
13773 vp.MaxZ = 1.0;
13775 hr = IDirect3DDevice9_SetViewport(device, &vp);
13776 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
13778 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13779 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13780 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13781 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13782 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13783 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13784 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13785 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13786 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13787 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13789 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
13790 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
13791 hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
13792 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
13793 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13794 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
13795 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
13796 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13797 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13798 D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
13799 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13801 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
13802 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13803 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
13804 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13806 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
13807 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13808 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
13809 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13811 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
13812 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13813 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
13814 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13816 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
13817 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13818 hr = IDirect3DDevice9_BeginScene(device);
13819 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13820 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13821 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13822 hr = IDirect3DDevice9_EndScene(device);
13823 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13825 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
13826 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13828 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13829 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13831 hr = IDirect3DDevice9_BeginScene(device);
13832 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13833 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13834 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13835 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
13836 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13837 hr = IDirect3DDevice9_EndScene(device);
13838 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13840 for (i = 0; i < 4; ++i)
13842 for (j = 0; j < 4; ++j)
13844 unsigned int x = 80 * ((2 * j) + 1);
13845 unsigned int y = 60 * ((2 * i) + 1);
13846 color = getPixelColor(device, x, y);
13847 ok(color_match(color, expected_colors[i][j], 0),
13848 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
13852 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13853 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13855 IDirect3DSurface9_Release(backbuffer);
13856 IDirect3DSurface9_Release(rt3);
13857 IDirect3DSurface9_Release(rt2);
13858 IDirect3DSurface9_Release(rt1);
13859 refcount = IDirect3DDevice9_Release(device);
13860 ok(!refcount, "Device has %u references left.\n", refcount);
13861 done:
13862 IDirect3D9_Release(d3d);
13863 DestroyWindow(window);
13866 /* Test that partial depth copies work the way they're supposed to. The clear
13867 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
13868 * the following draw should only copy back the part that was modified. */
13869 static void depth_buffer2_test(void)
13871 static const struct
13873 struct vec3 position;
13874 DWORD diffuse;
13876 quad[] =
13878 {{-1.0f, 1.0f, 0.66f}, 0xffff0000},
13879 {{ 1.0f, 1.0f, 0.66f}, 0xffff0000},
13880 {{-1.0f, -1.0f, 0.66f}, 0xffff0000},
13881 {{ 1.0f, -1.0f, 0.66f}, 0xffff0000},
13884 IDirect3DSurface9 *backbuffer, *rt1, *rt2;
13885 IDirect3DDevice9 *device;
13886 unsigned int i, j;
13887 D3DVIEWPORT9 vp;
13888 IDirect3D9 *d3d;
13889 D3DCOLOR color;
13890 ULONG refcount;
13891 HWND window;
13892 HRESULT hr;
13894 window = create_window();
13895 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13896 ok(!!d3d, "Failed to create a D3D object.\n");
13897 if (!(device = create_device(d3d, window, window, TRUE)))
13899 skip("Failed to create a D3D device, skipping tests.\n");
13900 goto done;
13903 vp.X = 0;
13904 vp.Y = 0;
13905 vp.Width = 640;
13906 vp.Height = 480;
13907 vp.MinZ = 0.0;
13908 vp.MaxZ = 1.0;
13910 hr = IDirect3DDevice9_SetViewport(device, &vp);
13911 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
13913 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13914 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13915 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13916 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13917 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13918 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13919 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13920 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13921 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13922 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13924 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13925 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
13926 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13927 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
13928 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
13929 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13930 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
13931 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
13933 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
13934 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13935 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
13936 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13938 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
13939 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13940 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
13941 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13943 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
13944 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13945 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
13946 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13948 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
13949 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13951 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13952 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13954 hr = IDirect3DDevice9_BeginScene(device);
13955 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13956 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13957 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13958 hr = IDirect3DDevice9_EndScene(device);
13959 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13961 for (i = 0; i < 4; ++i)
13963 for (j = 0; j < 4; ++j)
13965 unsigned int x = 80 * ((2 * j) + 1);
13966 unsigned int y = 60 * ((2 * i) + 1);
13967 color = getPixelColor(device, x, y);
13968 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
13969 "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
13973 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13974 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13976 IDirect3DSurface9_Release(backbuffer);
13977 IDirect3DSurface9_Release(rt2);
13978 IDirect3DSurface9_Release(rt1);
13979 refcount = IDirect3DDevice9_Release(device);
13980 ok(!refcount, "Device has %u references left.\n", refcount);
13981 done:
13982 IDirect3D9_Release(d3d);
13983 DestroyWindow(window);
13986 static void depth_blit_test(void)
13988 static const struct
13990 struct vec3 position;
13991 DWORD diffuse;
13993 quad1[] =
13995 {{-1.0f, 1.0f, 0.33f}, 0xff00ff00},
13996 {{ 1.0f, 1.0f, 0.33f}, 0xff00ff00},
13997 {{-1.0f, -1.0f, 0.33f}, 0xff00ff00},
13998 {{ 1.0f, -1.0f, 0.33f}, 0xff00ff00},
14000 quad2[] =
14002 {{-1.0f, 1.0f, 0.66f}, 0xff0000ff},
14003 {{ 1.0f, 1.0f, 0.66f}, 0xff0000ff},
14004 {{-1.0f, -1.0f, 0.66f}, 0xff0000ff},
14005 {{ 1.0f, -1.0f, 0.66f}, 0xff0000ff},
14007 static const DWORD expected_colors[4][4] =
14009 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
14010 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
14011 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
14012 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
14015 IDirect3DSurface9 *backbuffer, *ds1, *ds2, *ds3;
14016 IDirect3DDevice9 *device;
14017 RECT src_rect, dst_rect;
14018 unsigned int i, j;
14019 D3DVIEWPORT9 vp;
14020 IDirect3D9 *d3d;
14021 D3DCOLOR color;
14022 ULONG refcount;
14023 HWND window;
14024 HRESULT hr;
14026 window = create_window();
14027 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14028 ok(!!d3d, "Failed to create a D3D object.\n");
14029 if (!(device = create_device(d3d, window, window, TRUE)))
14031 skip("Failed to create a D3D device, skipping tests.\n");
14032 goto done;
14035 vp.X = 0;
14036 vp.Y = 0;
14037 vp.Width = 640;
14038 vp.Height = 480;
14039 vp.MinZ = 0.0;
14040 vp.MaxZ = 1.0;
14042 hr = IDirect3DDevice9_SetViewport(device, &vp);
14043 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
14045 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
14046 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14047 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
14048 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
14049 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
14050 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
14051 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
14052 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14053 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 320, 240, D3DFMT_D24S8, 0, 0, FALSE, &ds3, NULL);
14054 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
14056 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14057 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14058 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14059 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14060 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
14061 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14062 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
14063 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14065 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14066 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14067 SetRect(&dst_rect, 0, 0, 480, 360);
14068 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
14069 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14070 SetRect(&dst_rect, 0, 0, 320, 240);
14071 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
14072 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14074 /* Partial blit. */
14075 SetRect(&src_rect, 0, 0, 320, 240);
14076 SetRect(&dst_rect, 0, 0, 320, 240);
14077 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
14078 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14079 /* Flipped. */
14080 SetRect(&src_rect, 0, 0, 640, 480);
14081 SetRect(&dst_rect, 0, 480, 640, 0);
14082 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
14083 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14084 /* Full, explicit. */
14085 SetRect(&src_rect, 0, 0, 640, 480);
14086 SetRect(&dst_rect, 0, 0, 640, 480);
14087 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
14088 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14089 /* Filtered blit. */
14090 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
14091 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14092 /* Depth -> color blit.*/
14093 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
14094 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14095 IDirect3DSurface9_Release(backbuffer);
14096 /* Full surface, different sizes */
14097 hr = IDirect3DDevice9_StretchRect(device, ds3, NULL, ds1, NULL, D3DTEXF_POINT);
14098 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14099 hr = IDirect3DDevice9_StretchRect(device, ds1, NULL, ds3, NULL, D3DTEXF_POINT);
14100 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14102 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
14103 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14104 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
14105 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14106 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
14107 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14109 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
14110 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14111 hr = IDirect3DDevice9_BeginScene(device);
14112 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14113 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
14114 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14115 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
14116 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14117 hr = IDirect3DDevice9_EndScene(device);
14118 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14120 for (i = 0; i < 4; ++i)
14122 for (j = 0; j < 4; ++j)
14124 unsigned int x = 80 * ((2 * j) + 1);
14125 unsigned int y = 60 * ((2 * i) + 1);
14126 color = getPixelColor(device, x, y);
14127 ok(color_match(color, expected_colors[i][j], 0),
14128 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
14132 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14133 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14135 IDirect3DSurface9_Release(ds3);
14136 IDirect3DSurface9_Release(ds2);
14137 IDirect3DSurface9_Release(ds1);
14138 refcount = IDirect3DDevice9_Release(device);
14139 ok(!refcount, "Device has %u references left.\n", refcount);
14140 done:
14141 IDirect3D9_Release(d3d);
14142 DestroyWindow(window);
14145 static void intz_test(void)
14147 static const DWORD ps_code[] =
14149 0xffff0200, /* ps_2_0 */
14150 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
14151 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
14152 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
14153 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
14154 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
14155 0x03010042, 0x800f0001, 0xb0e40000, 0xa0e40800, /* texldp r1, t0, s0 */
14156 0x02000001, 0x80020000, 0x80000001, /* mov r0.y, r1.x */
14157 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14158 0x0000ffff, /* end */
14160 struct
14162 float x, y, z;
14163 float s, t, p, q;
14165 quad[] =
14167 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
14168 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
14169 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
14170 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
14172 half_quad_1[] =
14174 { -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
14175 { 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
14176 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
14177 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
14179 half_quad_2[] =
14181 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
14182 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
14183 { -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
14184 { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
14186 struct
14188 UINT x, y;
14189 D3DCOLOR color;
14191 expected_colors[] =
14193 { 80, 100, 0x20204020},
14194 {240, 100, 0x6060bf60},
14195 {400, 100, 0x9f9f409f},
14196 {560, 100, 0xdfdfbfdf},
14197 { 80, 450, 0x20204020},
14198 {240, 450, 0x6060bf60},
14199 {400, 450, 0x9f9f409f},
14200 {560, 450, 0xdfdfbfdf},
14203 IDirect3DSurface9 *original_rt, *rt;
14204 struct surface_readback rb;
14205 IDirect3DTexture9 *texture;
14206 IDirect3DPixelShader9 *ps;
14207 IDirect3DDevice9 *device;
14208 IDirect3DSurface9 *ds;
14209 IDirect3D9 *d3d;
14210 ULONG refcount;
14211 D3DCAPS9 caps;
14212 HWND window;
14213 HRESULT hr;
14214 UINT i;
14216 window = create_window();
14217 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14218 ok(!!d3d, "Failed to create a D3D object.\n");
14219 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
14220 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
14222 skip("No INTZ support, skipping INTZ test.\n");
14223 goto done;
14225 if (!(device = create_device(d3d, window, window, TRUE)))
14227 skip("Failed to create a D3D device, skipping tests.\n");
14228 goto done;
14231 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14232 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
14233 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
14235 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
14236 IDirect3DDevice9_Release(device);
14237 goto done;
14239 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
14241 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
14242 IDirect3DDevice9_Release(device);
14243 goto done;
14246 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14247 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14249 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
14250 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
14251 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
14252 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
14253 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
14254 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
14255 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
14256 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
14258 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
14259 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14260 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14261 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14262 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
14263 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14264 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14265 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14266 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14267 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14269 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
14270 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14271 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
14272 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14273 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
14274 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14275 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
14276 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14277 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
14278 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14280 /* Render offscreen, using the INTZ texture as depth buffer */
14281 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14282 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14283 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14284 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14285 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14286 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14287 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14288 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14290 /* Setup the depth/stencil surface. */
14291 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14292 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14294 hr = IDirect3DDevice9_BeginScene(device);
14295 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14296 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14297 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14298 hr = IDirect3DDevice9_EndScene(device);
14299 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14301 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14302 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14303 IDirect3DSurface9_Release(ds);
14304 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14305 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14306 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14307 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14308 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14309 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14311 /* Read the depth values back. */
14312 hr = IDirect3DDevice9_BeginScene(device);
14313 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14314 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14315 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14316 hr = IDirect3DDevice9_EndScene(device);
14317 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14319 get_rt_readback(original_rt, &rb);
14320 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14322 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
14323 ok(color_match(color, expected_colors[i].color, 1),
14324 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14325 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14327 release_surface_readback(&rb);
14329 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14330 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14332 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14333 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14334 IDirect3DTexture9_Release(texture);
14336 /* Render onscreen while using the INTZ texture as depth buffer */
14337 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
14338 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
14339 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14340 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14341 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14342 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14343 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14344 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14346 /* Setup the depth/stencil surface. */
14347 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14348 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14350 hr = IDirect3DDevice9_BeginScene(device);
14351 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14352 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14353 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14354 hr = IDirect3DDevice9_EndScene(device);
14355 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14357 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14358 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14359 IDirect3DSurface9_Release(ds);
14360 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14361 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14362 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14363 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14365 /* Read the depth values back. */
14366 hr = IDirect3DDevice9_BeginScene(device);
14367 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14368 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14369 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14370 hr = IDirect3DDevice9_EndScene(device);
14371 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14373 get_rt_readback(original_rt, &rb);
14374 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14376 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
14377 ok(color_match(color, expected_colors[i].color, 1),
14378 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14379 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14381 release_surface_readback(&rb);
14383 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14384 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14386 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14387 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14388 IDirect3DTexture9_Release(texture);
14390 /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
14391 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
14392 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
14393 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14394 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14396 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14397 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14398 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14399 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14400 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14401 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14403 /* Setup the depth/stencil surface. */
14404 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14405 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14407 hr = IDirect3DDevice9_BeginScene(device);
14408 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14409 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
14410 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14411 hr = IDirect3DDevice9_EndScene(device);
14412 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14414 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14415 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14417 hr = IDirect3DDevice9_BeginScene(device);
14418 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14419 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
14420 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14421 hr = IDirect3DDevice9_EndScene(device);
14422 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14424 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14425 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14426 IDirect3DSurface9_Release(ds);
14427 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14428 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14429 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14430 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14432 /* Read the depth values back. */
14433 hr = IDirect3DDevice9_BeginScene(device);
14434 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14435 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14436 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14437 hr = IDirect3DDevice9_EndScene(device);
14438 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14440 get_rt_readback(original_rt, &rb);
14441 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14443 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
14444 ok(color_match(color, expected_colors[i].color, 1),
14445 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14446 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14448 release_surface_readback(&rb);
14450 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14451 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14453 IDirect3DTexture9_Release(texture);
14454 IDirect3DPixelShader9_Release(ps);
14455 IDirect3DSurface9_Release(original_rt);
14456 IDirect3DSurface9_Release(rt);
14457 refcount = IDirect3DDevice9_Release(device);
14458 ok(!refcount, "Device has %u references left.\n", refcount);
14459 done:
14460 IDirect3D9_Release(d3d);
14461 DestroyWindow(window);
14464 static void shadow_test(void)
14466 static const DWORD ps_code[] =
14468 0xffff0200, /* ps_2_0 */
14469 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
14470 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
14471 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
14472 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
14473 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
14474 0x03010042, 0x800f0001, 0xb0e40000, 0xa0e40800, /* texldp r1, t0, s0 */
14475 0x02000001, 0x80020000, 0x80000001, /* mov r0.y, r1.x */
14476 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14477 0x0000ffff, /* end */
14479 struct
14481 D3DFORMAT format;
14482 const char *name;
14484 formats[] =
14486 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
14487 {D3DFMT_D32, "D3DFMT_D32"},
14488 {D3DFMT_D15S1, "D3DFMT_D15S1"},
14489 {D3DFMT_D24S8, "D3DFMT_D24S8"},
14490 {D3DFMT_D24X8, "D3DFMT_D24X8"},
14491 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
14492 {D3DFMT_D16, "D3DFMT_D16"},
14493 {D3DFMT_D32F_LOCKABLE, "D3DFMT_D32F_LOCKABLE"},
14494 {D3DFMT_D24FS8, "D3DFMT_D24FS8"},
14496 struct
14498 float x, y, z;
14499 float s, t, p, q;
14501 quad[] =
14503 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
14504 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
14505 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
14506 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
14508 struct
14510 UINT x, y;
14511 D3DCOLOR color;
14513 expected_colors[] =
14515 {400, 60, 0x00000000},
14516 {560, 180, 0xffff00ff},
14517 {560, 300, 0xffff00ff},
14518 {400, 420, 0xffffffff},
14519 {240, 420, 0xffffffff},
14520 { 80, 300, 0x00000000},
14521 { 80, 180, 0x00000000},
14522 {240, 60, 0x00000000},
14525 IDirect3DSurface9 *original_ds, *original_rt, *rt;
14526 struct surface_readback rb;
14527 IDirect3DPixelShader9 *ps;
14528 IDirect3DDevice9 *device;
14529 IDirect3D9 *d3d;
14530 ULONG refcount;
14531 D3DCAPS9 caps;
14532 HWND window;
14533 HRESULT hr;
14534 UINT i;
14536 window = create_window();
14537 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14538 ok(!!d3d, "Failed to create a D3D object.\n");
14539 if (!(device = create_device(d3d, window, window, TRUE)))
14541 skip("Failed to create a D3D device, skipping tests.\n");
14542 goto done;
14545 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14546 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
14547 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
14549 skip("No pixel shader 2.0 support, skipping shadow test.\n");
14550 IDirect3DDevice9_Release(device);
14551 goto done;
14554 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14555 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14556 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
14557 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
14559 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
14560 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
14561 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
14562 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
14563 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
14565 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
14566 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14567 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14568 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14569 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
14570 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14571 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14572 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14573 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14574 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14576 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
14577 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14578 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
14579 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14580 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
14581 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14582 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
14583 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14584 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
14585 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14587 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
14589 D3DFORMAT format = formats[i].format;
14590 IDirect3DTexture9 *texture;
14591 IDirect3DSurface9 *ds;
14592 unsigned int j;
14594 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
14595 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format)))
14596 continue;
14598 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
14599 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
14600 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
14602 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14603 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14605 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14606 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14608 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14609 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14611 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14612 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14614 /* Setup the depth/stencil surface. */
14615 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14616 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14618 hr = IDirect3DDevice9_BeginScene(device);
14619 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14620 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14621 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14622 hr = IDirect3DDevice9_EndScene(device);
14623 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14625 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14626 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14627 IDirect3DSurface9_Release(ds);
14629 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14630 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14632 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14633 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14635 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14636 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14638 /* Do the actual shadow mapping. */
14639 hr = IDirect3DDevice9_BeginScene(device);
14640 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14641 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14642 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14643 hr = IDirect3DDevice9_EndScene(device);
14644 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14646 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14647 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14648 IDirect3DTexture9_Release(texture);
14650 get_rt_readback(original_rt, &rb);
14651 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
14653 D3DCOLOR color = get_readback_color(&rb, expected_colors[j].x, expected_colors[j].y);
14654 ok(color_match(color, expected_colors[j].color, 0),
14655 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
14656 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
14657 formats[i].name, color);
14659 release_surface_readback(&rb);
14661 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14662 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14665 IDirect3DPixelShader9_Release(ps);
14666 IDirect3DSurface9_Release(original_ds);
14667 IDirect3DSurface9_Release(original_rt);
14668 IDirect3DSurface9_Release(rt);
14669 refcount = IDirect3DDevice9_Release(device);
14670 ok(!refcount, "Device has %u references left.\n", refcount);
14671 done:
14672 IDirect3D9_Release(d3d);
14673 DestroyWindow(window);
14676 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
14678 static const struct
14680 struct vec3 position;
14681 DWORD diffuse;
14683 quad1[] =
14685 {{-1.0f, -1.0f, 0.0f}, 0xfff9e814},
14686 {{-1.0f, 1.0f, 0.0f}, 0xfff9e814},
14687 {{ 1.0f, -1.0f, 0.0f}, 0xfff9e814},
14688 {{ 1.0f, 1.0f, 0.0f}, 0xfff9e814},
14690 quad2[] =
14692 {{-1.0f, -1.0f, 0.0f}, 0xff002b7f},
14693 {{-1.0f, 1.0f, 0.0f}, 0xff002b7f},
14694 {{ 1.0f, -1.0f, 0.0f}, 0xff002b7f},
14695 {{ 1.0f, 1.0f, 0.0f}, 0xff002b7f},
14697 D3DCOLOR color;
14698 HRESULT hr;
14700 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
14701 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14703 hr = IDirect3DDevice9_BeginScene(device);
14704 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14706 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
14707 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14709 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
14710 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14711 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
14712 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14714 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
14715 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14716 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
14717 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14719 hr = IDirect3DDevice9_EndScene(device);
14720 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14722 color = getPixelColor(device, 1, 240);
14723 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
14724 color = getPixelColor(device, 638, 240);
14725 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
14727 color = getPixelColor(device, 1, 241);
14728 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
14729 color = getPixelColor(device, 638, 241);
14730 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
14733 static void clip_planes_test(void)
14735 IDirect3DSurface9 *offscreen_surface, *original_rt;
14736 IDirect3DTexture9 *offscreen = NULL;
14737 IDirect3DVertexShader9 *shader;
14738 IDirect3DDevice9 *device;
14739 IDirect3D9 *d3d;
14740 ULONG refcount;
14741 D3DCAPS9 caps;
14742 HWND window;
14743 HRESULT hr;
14745 static const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
14746 static const DWORD shader_code[] =
14748 0xfffe0200, /* vs_2_0 */
14749 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
14750 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
14751 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
14752 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
14753 0x0000ffff /* end */
14756 window = create_window();
14757 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14758 ok(!!d3d, "Failed to create a D3D object.\n");
14759 if (!(device = create_device(d3d, window, window, TRUE)))
14761 skip("Failed to create a D3D device, skipping tests.\n");
14762 goto done;
14765 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14766 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
14767 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
14769 skip("No vs_2_0 support, skipping tests.\n");
14770 IDirect3DDevice9_Release(device);
14771 goto done;
14774 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14775 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14777 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14778 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14779 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
14780 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14781 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
14782 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14783 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
14784 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14786 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
14787 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
14788 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14789 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
14791 IDirect3DDevice9_SetClipPlane(device, 0, plane0);
14793 clip_planes(device, "Onscreen FFP");
14795 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
14796 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
14797 hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
14798 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14799 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
14800 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
14802 clip_planes(device, "Offscreen FFP");
14804 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14805 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14807 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
14808 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
14809 hr = IDirect3DDevice9_SetVertexShader(device, shader);
14810 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
14812 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14813 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
14815 clip_planes(device, "Onscreen vertex shader");
14817 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
14818 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
14820 clip_planes(device, "Offscreen vertex shader");
14822 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14823 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14825 IDirect3DVertexShader9_Release(shader);
14826 IDirect3DSurface9_Release(original_rt);
14827 IDirect3DSurface9_Release(offscreen_surface);
14828 IDirect3DTexture9_Release(offscreen);
14829 refcount = IDirect3DDevice9_Release(device);
14830 ok(!refcount, "Device has %u references left.\n", refcount);
14831 done:
14832 IDirect3D9_Release(d3d);
14833 DestroyWindow(window);
14836 static void fp_special_test(void)
14838 /* Microsoft's assembler generates nan and inf with "1.#QNAN" and "1.#INF." respectively */
14839 static const DWORD vs_header[] =
14841 0xfffe0200, /* vs_2_0 */
14842 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
14843 0x05000051, 0xa00f0001, 0x7fc00000, 0xff800000, 0x7f800000, 0x00000000, /* def c1, nan, -inf, inf, 0 */
14844 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
14845 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
14848 static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001}; /* log r0.x, v1.x */
14849 static const DWORD vs_pow[] =
14850 {0x03000020, 0x80010000, 0x90000001, 0x90000001}; /* pow r0.x, v1.x, v1.x */
14851 static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001}; /* nrm r0.xyz, v1.x */
14852 static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001}; /* rcp r0.x, v1.x */
14853 static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001}; /* rcp r0.x, -v1.x */
14854 static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001}; /* rsq r0.x, v1.x */
14855 static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001}; /* rsq r0.x, -v1.x */
14856 static const DWORD vs_lit[] = {0x02000010, 0x800f0000, 0x90000001, /* lit r0, v1.xxxx */
14857 0x02000001, 0x80010000, 0x80aa0000}; /* mov r0.x, v0.z */
14858 static const DWORD vs_def1[] = {0x02000001, 0x80010000, 0xa0000001}; /* mov r0.x, c1.x */
14859 static const DWORD vs_def2[] = {0x02000001, 0x80010000, 0xa0550001}; /* mov r0.x, c1.y */
14860 static const DWORD vs_def3[] = {0x02000001, 0x80010000, 0xa0aa0001}; /* mov r0.x, c1.z */
14862 static const DWORD vs_footer[] =
14864 0x03000005, 0x80020000, 0x80000000, 0xa0ff0000, /* mul r0.y, r0.x, c0.w */
14865 0x0300000d, 0x80040000, 0x80000000, 0x80550000, /* sge r0.z, r0.x, r0.y */
14866 0x0300000d, 0x80020000, 0x80e40000, 0x80000000, /* sge r0.y, r0, r0.x */
14867 0x03000005, 0x80040000, 0x80550000, 0x80e40000, /* mul r0.z, r0.y, r0 */
14868 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
14869 0x0300000c, 0x80020000, 0x80000000, 0x80000000, /* slt r0.y, r0.x, r0.x */
14870 0x03000002, 0x80040000, 0x80550000, 0x80550000, /* add r0.z, r0.y, r0.y */
14871 0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000, /* slt r0.y, c0.x, r0.w */
14872 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
14873 0x03000002, 0x80040000, 0x81550000, 0xa0e40000, /* add r0.z, -r0.y, c0 */
14874 0x0300000c, 0x80080000, 0xa0000000, 0x80e40000, /* slt r0.w, c0.x, r0 */
14875 0x03000005, 0x80040000, 0x80ff0000, 0x80e40000, /* mul r0.z, r0.w, r0 */
14876 0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000, /* mad r0.y, r0.z, c0, r0 */
14877 0x02000001, 0xe0030000, 0x80e40000, /* mov oT0.xy, r0 */
14878 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
14879 0x0000ffff, /* end */
14882 static const struct
14884 const char *name;
14885 const DWORD *ops;
14886 DWORD size;
14887 D3DCOLOR r500;
14888 D3DCOLOR r600;
14889 D3DCOLOR nv40;
14890 D3DCOLOR nv50;
14891 D3DCOLOR warp;
14893 vs_body[] =
14895 /* The basic ideas here are:
14896 * 2.0 * +/-INF == +/-INF
14897 * NAN != NAN
14899 * The vertex shader value is written to the red component, with 0.0
14900 * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
14901 * result in 0x00. The pixel shader value is written to the green
14902 * component, but here 0.0 also results in 0x00. The actual value is
14903 * written to the blue component.
14905 * There are considerable differences between graphics cards in how
14906 * these are handled, but pow and nrm never generate INF or NAN on
14907 * real hardware. */
14908 {"log", vs_log, sizeof(vs_log), 0x00000000, 0x00000000, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
14909 {"pow", vs_pow, sizeof(vs_pow), 0x000000ff, 0x000000ff, 0x0000ff00, 0x000000ff, 0x00008000},
14910 {"nrm", vs_nrm, sizeof(vs_nrm), 0x00ff0000, 0x00ff0000, 0x0000ff00, 0x00ff0000, 0x00008000},
14911 {"rcp1", vs_rcp1, sizeof(vs_rcp1), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
14912 {"rcp2", vs_rcp2, sizeof(vs_rcp2), 0x000000ff, 0x00000000, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
14913 {"rsq1", vs_rsq1, sizeof(vs_rsq1), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
14914 {"rsq2", vs_rsq2, sizeof(vs_rsq2), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
14915 {"lit", vs_lit, sizeof(vs_lit), 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
14916 {"def1", vs_def1, sizeof(vs_def1), 0x000000ff, 0x00007f00, 0x0000ff00, 0x00007f00, 0x00008000},
14917 {"def2", vs_def2, sizeof(vs_def2), 0x00ff0000, 0x00ff7f00, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
14918 {"def3", vs_def3, sizeof(vs_def3), 0x00ff00ff, 0x00ff7f00, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
14921 static const DWORD ps_code[] =
14923 0xffff0200, /* ps_2_0 */
14924 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
14925 0x0200001f, 0x80000000, 0xb0030000, /* dcl t0.xy */
14926 0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000, /* max r1.x, t0, c0 */
14927 0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000, /* min r0.x, t0, c0 */
14928 0x03000002, 0x80010000, 0x80e40000, 0x81e40001, /* add r0.x, r0, -r1 */
14929 0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000, /* mad r1.x, t0, c0.w. -t0 */
14930 0x02000023, 0x80010002, 0x80e40001, /* abs r2.x, r1 */
14931 0x02000023, 0x80010000, 0x80e40000, /* abs r0.x, r0 */
14932 0x02000023, 0x80010001, 0xb0e40000, /* abs r1.x, t0 */
14933 0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r2, c0.z, c0 */
14934 0x02000023, 0x80010002, 0x80e40002, /* abs r2.x, r2 */
14935 0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r1.x, -r1, c0.z, c0 */
14936 0x02000023, 0x80010001, 0x80e40001, /* abs r1.x, r1 */
14937 0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r3.x, -r2, c0.z, c0 */
14938 0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r1, c0.z, c0 */
14939 0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000, /* cmp r0.x, -r0, c0.y, c0 */
14940 0x03000005, 0x80010002, 0x80e40002, 0x80e40003, /* mul r2.x, r2, r3 */
14941 0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000, /* cmp r0.x, -r2, c0.z, r0 */
14942 0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000, /* cmp r0.y, -r1.x, r0.x, c0.x */
14943 0x02000001, 0x80050000, 0xb0c90000, /* mov r0.xz, t0.yzxw */
14944 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.w, c0.z */
14945 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14946 0x0000ffff, /* end */
14949 struct
14951 float x, y, z;
14952 float s;
14954 quad[] =
14956 { -1.0f, 1.0f, 0.0f, 0.0f},
14957 { 1.0f, 1.0f, 1.0f, 0.0f},
14958 { -1.0f, -1.0f, 0.0f, 0.0f},
14959 { 1.0f, -1.0f, 1.0f, 0.0f},
14962 IDirect3DPixelShader9 *ps;
14963 IDirect3DDevice9 *device;
14964 UINT body_size = 0;
14965 IDirect3D9 *d3d;
14966 DWORD *vs_code;
14967 ULONG refcount;
14968 D3DCAPS9 caps;
14969 HWND window;
14970 HRESULT hr;
14971 UINT i;
14973 window = create_window();
14974 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14975 ok(!!d3d, "Failed to create a D3D object.\n");
14976 if (!(device = create_device(d3d, window, window, TRUE)))
14978 skip("Failed to create a D3D device, skipping tests.\n");
14979 goto done;
14982 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14983 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
14984 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
14986 skip("No shader model 2.0 support, skipping floating point specials test.\n");
14987 IDirect3DDevice9_Release(device);
14988 goto done;
14991 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
14992 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14994 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
14995 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
14996 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14997 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14999 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
15000 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15002 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
15003 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
15005 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
15007 if (vs_body[i].size > body_size) body_size = vs_body[i].size;
15010 vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
15011 memcpy(vs_code, vs_header, sizeof(vs_header));
15013 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
15015 DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
15016 IDirect3DVertexShader9 *vs;
15017 D3DCOLOR color;
15019 memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
15020 offset += vs_body[i].size / sizeof(*vs_body[i].ops);
15021 memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
15023 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
15024 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
15025 hr = IDirect3DDevice9_SetVertexShader(device, vs);
15026 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
15028 hr = IDirect3DDevice9_BeginScene(device);
15029 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15030 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15031 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15032 hr = IDirect3DDevice9_EndScene(device);
15033 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15035 color = getPixelColor(device, 320, 240);
15036 ok(color_match(color, vs_body[i].r500, 1)
15037 || color_match(color, vs_body[i].r600, 1)
15038 || color_match(color, vs_body[i].nv40, 1)
15039 || color_match(color, vs_body[i].nv50, 1)
15040 || broken(color_match(color, vs_body[i].warp, 1)),
15041 "Expected color 0x%08x, 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
15042 vs_body[i].r500, vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
15044 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15045 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
15047 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
15048 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
15049 IDirect3DVertexShader9_Release(vs);
15052 HeapFree(GetProcessHeap(), 0, vs_code);
15054 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
15055 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
15056 IDirect3DPixelShader9_Release(ps);
15057 refcount = IDirect3DDevice9_Release(device);
15058 ok(!refcount, "Device has %u references left.\n", refcount);
15059 done:
15060 IDirect3D9_Release(d3d);
15061 DestroyWindow(window);
15064 static void srgbwrite_format_test(void)
15066 IDirect3D9 *d3d;
15067 IDirect3DSurface9 *rt, *backbuffer;
15068 IDirect3DTexture9 *texture;
15069 IDirect3DDevice9 *device;
15070 ULONG refcount;
15071 HWND window;
15072 HRESULT hr;
15073 int i;
15074 DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
15075 static const struct
15077 D3DFORMAT fmt;
15078 const char *name;
15080 formats[] =
15082 { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
15083 { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
15084 { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
15085 { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
15086 { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
15088 static const struct
15090 float x, y, z;
15091 float u, v;
15093 quad[] =
15095 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
15096 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
15097 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
15098 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
15101 window = create_window();
15102 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15103 ok(!!d3d, "Failed to create a D3D object.\n");
15104 if (!(device = create_device(d3d, window, window, TRUE)))
15106 skip("Failed to create a D3D device, skipping tests.\n");
15107 goto done;
15110 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
15111 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15112 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
15113 ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
15114 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
15115 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
15116 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
15117 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15119 for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
15121 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
15122 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
15124 skip("Format %s not supported as render target, skipping test.\n",
15125 formats[i].name);
15126 continue;
15129 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET,
15130 formats[i].fmt, D3DPOOL_DEFAULT, &texture, NULL);
15131 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
15132 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
15133 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
15135 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
15136 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
15137 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15138 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
15139 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
15140 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
15142 hr = IDirect3DDevice9_BeginScene(device);
15143 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15145 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
15146 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
15147 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
15148 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
15149 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15150 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15152 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
15153 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
15154 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
15155 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15156 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
15157 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
15158 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
15159 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
15160 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15161 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15162 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15163 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
15165 hr = IDirect3DDevice9_EndScene(device);
15166 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15168 IDirect3DSurface9_Release(rt);
15169 IDirect3DTexture9_Release(texture);
15171 color = getPixelColor(device, 360, 240);
15172 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
15173 D3DUSAGE_QUERY_SRGBWRITE,
15174 D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
15176 /* Big slop for R5G6B5 */
15177 ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
15178 formats[i].name, color_srgb, color);
15180 else
15182 /* Big slop for R5G6B5 */
15183 ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
15184 formats[i].name, color_rgb, color);
15187 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15188 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
15191 IDirect3DSurface9_Release(backbuffer);
15192 refcount = IDirect3DDevice9_Release(device);
15193 ok(!refcount, "Device has %u references left.\n", refcount);
15194 done:
15195 IDirect3D9_Release(d3d);
15196 DestroyWindow(window);
15199 static void ds_size_test(void)
15201 IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
15202 IDirect3DDevice9 *device;
15203 DWORD num_passes;
15204 IDirect3D9 *d3d;
15205 ULONG refcount;
15206 HWND window;
15207 HRESULT hr;
15209 static const struct
15211 float x, y, z;
15213 quad[] =
15215 {-1.0f, -1.0f, 0.0f},
15216 {-1.0f, 1.0f, 0.0f},
15217 { 1.0f, -1.0f, 0.0f},
15218 { 1.0f, 1.0f, 0.0f},
15221 window = create_window();
15222 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15223 ok(!!d3d, "Failed to create a D3D object.\n");
15224 if (!(device = create_device(d3d, window, window, TRUE)))
15226 skip("Failed to create a D3D device, skipping tests.\n");
15227 goto done;
15230 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
15231 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
15232 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
15233 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#x.\n", hr);
15234 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
15235 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
15237 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
15238 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
15240 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
15241 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15242 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
15243 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15244 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
15245 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15246 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15247 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
15248 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
15249 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
15250 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
15251 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#x.\n", hr);
15252 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15253 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
15254 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15255 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
15256 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15257 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
15259 /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
15260 * but does not change the surface's contents. */
15261 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
15262 ok(SUCCEEDED(hr), "Target clear failed, hr %#x.\n", hr);
15263 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
15264 ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#x.\n", hr);
15265 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
15266 ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#x.\n", hr);
15268 /* Nvidia does not clear the surface(The color is still 0x000000ff), AMD does(the color is 0x00ff0000) */
15270 /* Turning on any depth-related state results in a ValidateDevice failure */
15271 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15272 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15273 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15274 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
15275 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
15276 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
15277 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15278 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15279 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15280 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15281 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
15282 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
15284 /* Try to draw with the device in an invalid state. */
15285 hr = IDirect3DDevice9_BeginScene(device);
15286 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15287 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15288 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15289 hr = IDirect3DDevice9_EndScene(device);
15290 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15292 /* Don't check the resulting draw unless we find an app that needs it. On
15293 * NVIDIA ValidateDevice() returns CONFLICTINGRENDERSTATE, so the result
15294 * is undefined. On AMD D3D seems to assume the stored Z buffer value is
15295 * 0.0 for all pixels, even those that are covered by the depth buffer. */
15297 hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
15298 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
15299 hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
15300 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
15301 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15302 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
15304 IDirect3DSurface9_Release(readback);
15305 IDirect3DSurface9_Release(ds);
15306 IDirect3DSurface9_Release(rt);
15307 IDirect3DSurface9_Release(old_rt);
15308 IDirect3DSurface9_Release(old_ds);
15309 refcount = IDirect3DDevice9_Release(device);
15310 ok(!refcount, "Device has %u references left.\n", refcount);
15311 done:
15312 IDirect3D9_Release(d3d);
15313 DestroyWindow(window);
15316 static void unbound_sampler_test(void)
15318 IDirect3DPixelShader9 *ps, *ps_cube, *ps_volume;
15319 IDirect3DSurface9 *rt, *old_rt;
15320 IDirect3DDevice9 *device;
15321 IDirect3D9 *d3d;
15322 ULONG refcount;
15323 D3DCAPS9 caps;
15324 DWORD color;
15325 HWND window;
15326 HRESULT hr;
15328 static const DWORD ps_code[] =
15330 0xffff0200, /* ps_2_0 */
15331 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
15332 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
15333 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
15334 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15335 0x0000ffff, /* end */
15337 static const DWORD ps_code_cube[] =
15339 0xffff0200, /* ps_2_0 */
15340 0x0200001f, 0x98000000, 0xa00f0800, /* dcl_cube s0 */
15341 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
15342 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
15343 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15344 0x0000ffff, /* end */
15346 static const DWORD ps_code_volume[] =
15348 0xffff0200, /* ps_2_0 */
15349 0x0200001f, 0xa0000000, 0xa00f0800, /* dcl_volume s0 */
15350 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
15351 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
15352 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15353 0x0000ffff, /* end */
15356 static const struct
15358 float x, y, z;
15359 float u, v;
15361 quad[] =
15363 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
15364 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
15365 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
15366 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
15369 window = create_window();
15370 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15371 ok(!!d3d, "Failed to create a D3D object.\n");
15372 if (!(device = create_device(d3d, window, window, TRUE)))
15374 skip("Failed to create a D3D device, skipping tests.\n");
15375 goto done;
15378 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15379 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
15380 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
15382 skip("No ps_2_0 support, skipping tests.\n");
15383 IDirect3DDevice9_Release(device);
15384 goto done;
15386 if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP) || !(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
15388 skip("No cube / volume texture support, skipping tests.\n");
15389 IDirect3DDevice9_Release(device);
15390 goto done;
15393 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15394 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStage failed, %#x.\n", hr);
15396 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
15397 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
15398 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_cube, &ps_cube);
15399 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
15400 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_volume, &ps_volume);
15401 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
15403 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
15404 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
15406 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
15407 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
15409 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15410 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
15412 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 );
15413 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
15415 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x56ffffff, 1.0f, 0);
15416 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
15418 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15419 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
15421 hr = IDirect3DDevice9_BeginScene(device);
15422 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15423 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15424 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15425 hr = IDirect3DDevice9_EndScene(device);
15426 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15428 color = getPixelColorFromSurface(rt, 32, 32);
15429 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
15431 /* Now try with a cube texture */
15432 hr = IDirect3DDevice9_SetPixelShader(device, ps_cube);
15433 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
15435 hr = IDirect3DDevice9_BeginScene(device);
15436 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15437 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15438 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15439 hr = IDirect3DDevice9_EndScene(device);
15440 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15442 color = getPixelColorFromSurface(rt, 32, 32);
15443 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
15445 /* And then with a volume texture */
15446 hr = IDirect3DDevice9_SetPixelShader(device, ps_volume);
15447 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
15449 hr = IDirect3DDevice9_BeginScene(device);
15450 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15451 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15452 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15453 hr = IDirect3DDevice9_EndScene(device);
15454 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15456 color = getPixelColorFromSurface(rt, 32, 32);
15457 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
15459 IDirect3DSurface9_Release(rt);
15460 IDirect3DSurface9_Release(old_rt);
15461 IDirect3DPixelShader9_Release(ps);
15462 IDirect3DPixelShader9_Release(ps_cube);
15463 IDirect3DPixelShader9_Release(ps_volume);
15464 refcount = IDirect3DDevice9_Release(device);
15465 ok(!refcount, "Device has %u references left.\n", refcount);
15466 done:
15467 IDirect3D9_Release(d3d);
15468 DestroyWindow(window);
15471 static void update_surface_test(void)
15473 static const BYTE blocks[][8] =
15475 {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, /* White */
15476 {0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Red */
15477 {0xe0, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00}, /* Yellow */
15478 {0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Green */
15479 {0xff, 0x07, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Cyan */
15480 {0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Blue */
15481 {0x1f, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Magenta */
15483 static const struct
15485 UINT x, y;
15486 D3DCOLOR color;
15488 expected_colors[] =
15490 { 18, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0xff)},
15491 { 57, 240, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff)},
15492 {109, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0xff)},
15493 {184, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
15494 {290, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
15495 {440, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
15496 {584, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
15498 static const struct
15500 float x, y, z, w;
15501 float u, v;
15503 tri[] =
15505 { 0.0f, 480.0f, 0.0f, 1.0f, 0.0f, 0.0f},
15506 { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
15507 {640.0f, 240.0f, 0.0f, 10.0f, 100.0f, 0.5f},
15509 static const RECT rect_2x2 = {0, 0, 2, 2};
15510 static const struct
15512 UINT src_level;
15513 UINT dst_level;
15514 const RECT *r;
15515 HRESULT hr;
15517 block_size_tests[] =
15519 {1, 0, NULL, D3D_OK},
15520 {0, 1, NULL, D3DERR_INVALIDCALL},
15521 {5, 4, NULL, D3DERR_INVALIDCALL},
15522 {4, 5, NULL, D3DERR_INVALIDCALL},
15523 {4, 5, &rect_2x2, D3DERR_INVALIDCALL},
15524 {5, 5, &rect_2x2, D3D_OK},
15527 IDirect3DSurface9 *src_surface, *dst_surface;
15528 IDirect3DTexture9 *src_tex, *dst_tex;
15529 IDirect3DDevice9 *device;
15530 IDirect3D9 *d3d;
15531 ULONG refcount;
15532 UINT count, i;
15533 HWND window;
15534 HRESULT hr;
15536 window = create_window();
15537 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15538 ok(!!d3d, "Failed to create a D3D object.\n");
15539 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15540 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1)))
15542 skip("DXT1 not supported, skipping tests.\n");
15543 goto done;
15545 if (!(device = create_device(d3d, window, window, TRUE)))
15547 skip("Failed to create a D3D device, skipping tests.\n");
15548 goto done;
15551 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &src_tex, NULL);
15552 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
15553 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &dst_tex, NULL);
15554 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
15556 count = IDirect3DTexture9_GetLevelCount(src_tex);
15557 ok(count == 7, "Got level count %u, expected 7.\n", count);
15559 for (i = 0; i < count; ++i)
15561 UINT row_count, block_count, x, y;
15562 D3DSURFACE_DESC desc;
15563 BYTE *row, *block;
15564 D3DLOCKED_RECT r;
15566 hr = IDirect3DTexture9_GetLevelDesc(src_tex, i, &desc);
15567 ok(SUCCEEDED(hr), "Failed to get level desc, hr %#x.\n", hr);
15569 hr = IDirect3DTexture9_LockRect(src_tex, i, &r, NULL, 0);
15570 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
15572 row_count = ((desc.Height + 3) & ~3) / 4;
15573 block_count = ((desc.Width + 3) & ~3) / 4;
15574 row = r.pBits;
15576 for (y = 0; y < row_count; ++y)
15578 block = row;
15579 for (x = 0; x < block_count; ++x)
15581 memcpy(block, blocks[i], sizeof(blocks[i]));
15582 block += sizeof(blocks[i]);
15584 row += r.Pitch;
15587 hr = IDirect3DTexture9_UnlockRect(src_tex, i);
15588 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
15591 for (i = 0; i < sizeof(block_size_tests) / sizeof(*block_size_tests); ++i)
15593 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, block_size_tests[i].src_level, &src_surface);
15594 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15595 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, block_size_tests[i].dst_level, &dst_surface);
15596 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15598 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, block_size_tests[i].r, dst_surface, NULL);
15599 ok(hr == block_size_tests[i].hr, "Update surface returned %#x for test %u, expected %#x.\n",
15600 hr, i, block_size_tests[i].hr);
15602 IDirect3DSurface9_Release(dst_surface);
15603 IDirect3DSurface9_Release(src_surface);
15606 for (i = 0; i < count; ++i)
15608 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, i, &src_surface);
15609 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15610 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, i, &dst_surface);
15611 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15613 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, NULL, dst_surface, NULL);
15614 ok(SUCCEEDED(hr), "Failed to update surface at level %u, hr %#x.\n", i, hr);
15616 IDirect3DSurface9_Release(dst_surface);
15617 IDirect3DSurface9_Release(src_surface);
15620 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15621 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15622 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
15623 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15624 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
15625 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15626 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)dst_tex);
15627 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
15628 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
15629 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
15630 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
15631 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
15633 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
15634 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
15636 hr = IDirect3DDevice9_BeginScene(device);
15637 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15638 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 1, tri, sizeof(*tri));
15639 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15640 hr = IDirect3DDevice9_EndScene(device);
15641 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15643 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15645 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
15646 ok(color_match(color, expected_colors[i].color, 0),
15647 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15648 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15651 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15652 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
15654 IDirect3DTexture9_Release(dst_tex);
15655 IDirect3DTexture9_Release(src_tex);
15656 refcount = IDirect3DDevice9_Release(device);
15657 ok(!refcount, "Device has %u references left.\n", refcount);
15658 done:
15659 IDirect3D9_Release(d3d);
15660 DestroyWindow(window);
15663 static void multisample_get_rtdata_test(void)
15665 IDirect3DSurface9 *original_ds, *original_rt, *rt, *readback;
15666 IDirect3DDevice9 *device;
15667 IDirect3D9 *d3d;
15668 ULONG refcount;
15669 HWND window;
15670 HRESULT hr;
15672 window = create_window();
15673 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15674 ok(!!d3d, "Failed to create a D3D object.\n");
15675 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15676 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15678 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping tests.\n");
15679 goto done;
15681 if (!(device = create_device(d3d, window, window, TRUE)))
15683 skip("Failed to create a D3D device, skipping tests.\n");
15684 goto done;
15687 hr = IDirect3DDevice9_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
15688 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
15689 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
15690 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_A8R8G8B8,
15691 D3DPOOL_SYSTEMMEM, &readback, NULL);
15692 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
15694 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
15695 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
15696 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
15697 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
15699 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15700 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15701 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15702 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15704 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
15705 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15706 hr = IDirect3DDevice9_GetRenderTargetData(device, rt, readback);
15707 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
15709 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
15710 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15711 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15712 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
15714 IDirect3DSurface9_Release(original_ds);
15715 IDirect3DSurface9_Release(original_rt);
15716 IDirect3DSurface9_Release(readback);
15717 IDirect3DSurface9_Release(rt);
15718 refcount = IDirect3DDevice9_Release(device);
15719 ok(!refcount, "Device has %u references left.\n", refcount);
15720 done:
15721 IDirect3D9_Release(d3d);
15722 DestroyWindow(window);
15725 static void multisampled_depth_buffer_test(void)
15727 IDirect3DDevice9 *device = 0;
15728 IDirect3DSurface9 *original_rt, *rt, *readback, *ds, *original_ds;
15729 IDirect3D9 *d3d;
15730 D3DCAPS9 caps;
15731 HRESULT hr;
15732 D3DPRESENT_PARAMETERS present_parameters;
15733 unsigned int i;
15734 static const struct
15736 float x, y, z;
15737 D3DCOLOR color;
15739 quad_1[] =
15741 { -1.0f, 1.0f, 0.0f, 0xffff0000},
15742 { 1.0f, 1.0f, 1.0f, 0xffff0000},
15743 { -1.0f, -1.0f, 0.0f, 0xffff0000},
15744 { 1.0f, -1.0f, 1.0f, 0xffff0000},
15746 quad_2[] =
15748 { -1.0f, 1.0f, 1.0f, 0xff0000ff},
15749 { 1.0f, 1.0f, 0.0f, 0xff0000ff},
15750 { -1.0f, -1.0f, 1.0f, 0xff0000ff},
15751 { 1.0f, -1.0f, 0.0f, 0xff0000ff},
15753 static const struct
15755 UINT x, y;
15756 D3DCOLOR color;
15758 expected_colors[] =
15760 { 80, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15761 {240, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15762 {400, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15763 {560, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15764 { 80, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15765 {240, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15766 {400, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15767 {560, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15770 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15771 ok(!!d3d, "Failed to create a D3D object.\n");
15773 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
15774 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15776 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled depth buffer test.\n");
15777 IDirect3D9_Release(d3d);
15778 return;
15780 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
15781 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15783 skip("Multisampling not supported for D3DFMT_D24S8, skipping multisampled depth buffer test.\n");
15784 IDirect3D9_Release(d3d);
15785 return;
15788 ZeroMemory(&present_parameters, sizeof(present_parameters));
15789 present_parameters.Windowed = TRUE;
15790 present_parameters.hDeviceWindow = create_window();
15791 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
15792 present_parameters.BackBufferWidth = 640;
15793 present_parameters.BackBufferHeight = 480;
15794 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
15795 present_parameters.EnableAutoDepthStencil = TRUE;
15796 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
15797 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
15799 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15800 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
15801 &present_parameters, &device);
15802 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
15804 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15805 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
15806 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
15808 skip("No unconditional NP2 texture support, skipping multisampled depth buffer test.\n");
15809 goto cleanup;
15812 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15813 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
15814 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
15815 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15816 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
15817 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
15819 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
15820 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
15821 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
15822 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
15824 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15825 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15826 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15827 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15828 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15829 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15830 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
15831 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15832 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
15833 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15835 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
15836 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15838 /* Render onscreen and then offscreen */
15839 hr = IDirect3DDevice9_BeginScene(device);
15840 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15841 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
15842 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15843 hr = IDirect3DDevice9_EndScene(device);
15844 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15846 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, rt, NULL, D3DTEXF_POINT);
15847 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15848 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15849 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15851 hr = IDirect3DDevice9_BeginScene(device);
15852 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15853 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
15854 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15855 hr = IDirect3DDevice9_EndScene(device);
15856 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15858 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, readback, NULL, D3DTEXF_POINT);
15859 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15861 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15863 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
15864 ok(color_match(color, expected_colors[i].color, 1),
15865 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15866 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15869 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
15870 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15871 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15872 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
15874 /* Render offscreen and then onscreen */
15875 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15876 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15877 IDirect3DSurface9_Release(ds);
15878 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
15879 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
15880 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#x.\n", hr);
15881 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15882 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15884 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
15885 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15887 hr = IDirect3DDevice9_BeginScene(device);
15888 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15889 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
15890 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15891 hr = IDirect3DDevice9_EndScene(device);
15892 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15894 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
15895 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15896 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15897 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15899 hr = IDirect3DDevice9_BeginScene(device);
15900 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15901 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
15902 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15903 hr = IDirect3DDevice9_EndScene(device);
15904 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15906 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
15907 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15909 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15911 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
15912 ok(color_match(color, expected_colors[i].color, 1),
15913 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15914 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15917 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15918 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
15920 IDirect3DSurface9_Release(ds);
15921 IDirect3DSurface9_Release(readback);
15922 IDirect3DSurface9_Release(rt);
15923 IDirect3DSurface9_Release(original_rt);
15924 cleanup_device(device);
15926 ZeroMemory(&present_parameters, sizeof(present_parameters));
15927 present_parameters.Windowed = TRUE;
15928 present_parameters.hDeviceWindow = create_window();
15929 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
15930 present_parameters.BackBufferWidth = 640;
15931 present_parameters.BackBufferHeight = 480;
15932 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
15933 present_parameters.EnableAutoDepthStencil = TRUE;
15934 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
15935 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
15937 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15938 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
15939 &present_parameters, &device);
15940 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
15942 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
15943 ok(SUCCEEDED(hr), "Failed to clear depth buffer, hr %#x.\n", hr);
15945 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15946 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
15947 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
15948 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15949 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
15950 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
15951 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
15952 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
15953 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
15955 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
15956 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
15957 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
15958 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
15959 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15960 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15961 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15962 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15964 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15965 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15966 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15967 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15968 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15969 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15970 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
15971 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15972 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
15973 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15975 /* Render to a multisampled offscreen frame buffer and then blit to
15976 * the onscreen (not multisampled) frame buffer. */
15977 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
15978 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15980 hr = IDirect3DDevice9_BeginScene(device);
15981 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15982 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
15983 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15984 hr = IDirect3DDevice9_EndScene(device);
15985 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15987 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
15988 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15989 hr = IDirect3DDevice9_StretchRect(device, ds, NULL, original_ds, NULL, D3DTEXF_POINT);
15990 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15992 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15993 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15994 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
15995 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15997 hr = IDirect3DDevice9_BeginScene(device);
15998 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15999 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
16000 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16001 hr = IDirect3DDevice9_EndScene(device);
16002 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16004 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
16005 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
16007 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16009 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
16010 ok(color_match(color, expected_colors[i].color, 1),
16011 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16012 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16015 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16016 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16018 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16019 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16020 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16021 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
16023 IDirect3DSurface9_Release(original_ds);
16024 IDirect3DSurface9_Release(original_rt);
16025 IDirect3DSurface9_Release(ds);
16026 IDirect3DSurface9_Release(readback);
16027 IDirect3DSurface9_Release(rt);
16028 cleanup:
16029 cleanup_device(device);
16030 IDirect3D9_Release(d3d);
16033 static void resz_test(void)
16035 IDirect3DDevice9 *device = 0;
16036 IDirect3DSurface9 *rt, *original_rt, *ds, *readback, *intz_ds;
16037 D3DCAPS9 caps;
16038 HRESULT hr;
16039 D3DPRESENT_PARAMETERS present_parameters;
16040 unsigned int i;
16041 static const DWORD ps_code[] =
16043 0xffff0200, /* ps_2_0 */
16044 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
16045 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
16046 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
16047 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
16048 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
16049 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
16050 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
16051 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
16052 0x02000001, 0x800f0800, 0x80e40001, /* mov oC0, r1 */
16053 0x0000ffff, /* end */
16055 struct
16057 float x, y, z;
16058 float s, t, p, q;
16060 quad[] =
16062 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
16063 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
16064 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
16065 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
16067 struct
16069 UINT x, y;
16070 D3DCOLOR color;
16072 expected_colors[] =
16074 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
16075 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
16076 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
16077 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
16078 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
16079 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
16080 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
16081 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
16083 IDirect3DTexture9 *texture;
16084 IDirect3DPixelShader9 *ps;
16085 IDirect3D9 *d3d;
16086 DWORD value;
16088 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16089 ok(!!d3d, "Failed to create a D3D object.\n");
16091 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
16092 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
16094 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
16095 IDirect3D9_Release(d3d);
16096 return;
16098 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
16099 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
16101 skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
16102 IDirect3D9_Release(d3d);
16103 return;
16106 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
16107 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
16109 skip("No INTZ support, skipping RESZ test.\n");
16110 IDirect3D9_Release(d3d);
16111 return;
16114 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
16115 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'))))
16117 skip("No RESZ support, skipping RESZ test.\n");
16118 IDirect3D9_Release(d3d);
16119 return;
16122 ZeroMemory(&present_parameters, sizeof(present_parameters));
16123 present_parameters.Windowed = TRUE;
16124 present_parameters.hDeviceWindow = create_window();
16125 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
16126 present_parameters.BackBufferWidth = 640;
16127 present_parameters.BackBufferHeight = 480;
16128 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
16129 present_parameters.EnableAutoDepthStencil = FALSE;
16130 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
16131 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
16133 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16134 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
16135 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
16137 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16138 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
16139 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
16141 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
16142 cleanup_device(device);
16143 IDirect3D9_Release(d3d);
16144 return;
16146 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
16148 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
16149 cleanup_device(device);
16150 IDirect3D9_Release(d3d);
16151 return;
16154 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
16155 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
16157 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
16158 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
16159 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
16160 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
16161 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
16162 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#x.\n", hr);
16163 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
16164 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
16165 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
16167 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
16168 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
16169 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
16170 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
16171 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
16172 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
16173 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16174 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
16175 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
16176 IDirect3DSurface9_Release(intz_ds);
16177 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
16178 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
16180 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
16181 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
16182 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
16183 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16184 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
16185 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16186 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16187 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16188 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16189 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16191 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
16192 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16193 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
16194 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16195 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
16196 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16197 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
16198 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16199 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
16200 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16202 /* Render offscreen (multisampled), blit the depth buffer
16203 * into the INTZ texture and then check its contents */
16204 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
16205 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16206 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16207 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16208 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
16209 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16211 hr = IDirect3DDevice9_BeginScene(device);
16212 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16213 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16214 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16216 /* The destination depth texture has to be bound to sampler 0 */
16217 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16218 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16220 /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
16221 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
16222 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16223 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
16224 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16225 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
16226 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16227 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16228 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16229 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
16230 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16231 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16232 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16233 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
16234 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16236 /* The actual multisampled depth buffer resolve happens here */
16237 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16238 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16239 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
16240 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
16242 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16243 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16244 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16245 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16246 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16247 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16249 /* Read the depth values back */
16250 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16251 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16252 hr = IDirect3DDevice9_EndScene(device);
16253 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16255 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16257 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
16258 ok(color_match(color, expected_colors[i].color, 1),
16259 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16260 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16263 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16264 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16266 IDirect3DSurface9_Release(ds);
16267 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16268 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16269 IDirect3DTexture9_Release(texture);
16270 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16271 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16272 IDirect3DPixelShader9_Release(ps);
16273 IDirect3DSurface9_Release(readback);
16274 IDirect3DSurface9_Release(original_rt);
16275 IDirect3DSurface9_Release(rt);
16276 cleanup_device(device);
16278 ZeroMemory(&present_parameters, sizeof(present_parameters));
16279 present_parameters.Windowed = TRUE;
16280 present_parameters.hDeviceWindow = create_window();
16281 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
16282 present_parameters.BackBufferWidth = 640;
16283 present_parameters.BackBufferHeight = 480;
16284 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
16285 present_parameters.EnableAutoDepthStencil = TRUE;
16286 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
16287 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
16289 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16290 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
16291 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
16293 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
16294 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
16295 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
16296 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
16297 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
16298 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
16299 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
16300 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
16301 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
16302 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
16303 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
16304 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
16305 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
16306 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16307 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
16308 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16309 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
16310 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
16311 IDirect3DSurface9_Release(intz_ds);
16312 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
16313 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
16315 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
16316 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
16317 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
16318 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16319 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
16320 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16321 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16322 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16323 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16324 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16326 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
16327 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16328 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
16329 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16330 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
16331 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16332 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
16333 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16334 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
16335 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16337 /* Render onscreen, blit the depth buffer into the INTZ texture
16338 * and then check its contents */
16339 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16340 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16341 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16342 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16343 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
16344 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16346 hr = IDirect3DDevice9_BeginScene(device);
16347 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16348 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16349 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16350 hr = IDirect3DDevice9_EndScene(device);
16351 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16353 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16354 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16356 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
16357 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16358 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
16359 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16360 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
16361 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16362 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16363 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16364 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
16365 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16366 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16367 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16368 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
16369 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16371 /* The actual multisampled depth buffer resolve happens here */
16372 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16373 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16374 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
16375 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
16377 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
16378 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16379 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16380 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16381 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16382 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16384 /* Read the depth values back */
16385 hr = IDirect3DDevice9_BeginScene(device);
16386 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16387 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16388 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16389 hr = IDirect3DDevice9_EndScene(device);
16390 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16392 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16394 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
16395 ok(color_match(color, expected_colors[i].color, 1),
16396 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16397 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16400 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16401 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16404 /* Test edge cases - try with no texture at all */
16405 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16406 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16407 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16408 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16409 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16410 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16411 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16412 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16414 hr = IDirect3DDevice9_BeginScene(device);
16415 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16416 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16417 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16418 hr = IDirect3DDevice9_EndScene(device);
16419 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16421 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16422 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16424 /* With a non-multisampled depth buffer */
16425 IDirect3DSurface9_Release(ds);
16426 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
16427 D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
16428 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
16430 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
16431 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16432 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16433 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16434 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16435 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16437 hr = IDirect3DDevice9_BeginScene(device);
16438 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16439 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16440 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16442 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16443 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16445 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
16446 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16447 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
16448 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16449 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
16450 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16451 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16452 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16453 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
16454 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16455 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16456 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16457 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
16458 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16459 hr = IDirect3DDevice9_EndScene(device);
16460 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16462 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16463 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16465 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16466 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16468 /* Read the depth values back. */
16469 hr = IDirect3DDevice9_BeginScene(device);
16470 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16471 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16472 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16473 hr = IDirect3DDevice9_EndScene(device);
16474 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16476 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16478 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
16479 ok(color_match(color, expected_colors[i].color, 1),
16480 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16481 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16484 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16485 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16487 /* Without a current depth-stencil buffer set */
16488 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16489 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16490 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16491 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16493 hr = IDirect3DDevice9_BeginScene(device);
16494 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16495 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16496 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16497 hr = IDirect3DDevice9_EndScene(device);
16498 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16500 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16501 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16503 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16504 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16505 IDirect3DSurface9_Release(ds);
16506 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16507 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16508 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16509 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16510 IDirect3DTexture9_Release(texture);
16511 IDirect3DPixelShader9_Release(ps);
16512 IDirect3DSurface9_Release(readback);
16513 IDirect3DSurface9_Release(original_rt);
16514 cleanup_device(device);
16515 IDirect3D9_Release(d3d);
16518 static void zenable_test(void)
16520 static const struct
16522 struct vec4 position;
16523 D3DCOLOR diffuse;
16525 tquad[] =
16527 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
16528 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xff00ff00},
16529 {{640.0f, 480.0f, 1.5f, 1.0f}, 0xff00ff00},
16530 {{640.0f, 0.0f, 1.5f, 1.0f}, 0xff00ff00},
16532 IDirect3DDevice9 *device;
16533 IDirect3D9 *d3d;
16534 D3DCOLOR color;
16535 ULONG refcount;
16536 D3DCAPS9 caps;
16537 HWND window;
16538 HRESULT hr;
16539 UINT x, y;
16540 UINT i, j;
16541 UINT test;
16542 IDirect3DSurface9 *ds;
16544 window = create_window();
16545 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16546 ok(!!d3d, "Failed to create a D3D object.\n");
16547 if (!(device = create_device(d3d, window, window, TRUE)))
16549 skip("Failed to create a D3D device, skipping tests.\n");
16550 goto done;
16553 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
16554 ok(SUCCEEDED(hr), "Failed to get depth stencil surface, hr %#x.\n", hr);
16556 for (test = 0; test < 2; ++test)
16558 /* The Windows 8 testbot (WARP) appears to clip with
16559 * ZENABLE = D3DZB_TRUE and no depth buffer set. */
16560 static const D3DCOLOR expected_broken[] =
16562 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16563 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16564 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16565 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16568 if (!test)
16570 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16571 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
16573 else
16575 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
16576 ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
16577 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16578 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
16579 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.0f, 0);
16580 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16582 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
16583 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16585 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
16586 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16587 hr = IDirect3DDevice9_BeginScene(device);
16588 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16589 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
16590 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16591 hr = IDirect3DDevice9_EndScene(device);
16592 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16594 for (i = 0; i < 4; ++i)
16596 for (j = 0; j < 4; ++j)
16598 x = 80 * ((2 * j) + 1);
16599 y = 60 * ((2 * i) + 1);
16600 color = getPixelColor(device, x, y);
16601 ok(color_match(color, 0x0000ff00, 1)
16602 || broken(color_match(color, expected_broken[i * 4 + j], 1) && !test),
16603 "Expected color 0x0000ff00 at %u, %u, got 0x%08x, test %u.\n",
16604 x, y, color, test);
16608 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16609 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
16612 IDirect3DSurface9_Release(ds);
16614 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16615 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
16617 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
16618 && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
16620 static const DWORD vs_code[] =
16622 0xfffe0101, /* vs_1_1 */
16623 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
16624 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
16625 0x00000001, 0xd00f0000, 0x90e40000, /* mov oD0, v0 */
16626 0x0000ffff
16628 static const DWORD ps_code[] =
16630 0xffff0101, /* ps_1_1 */
16631 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
16632 0x0000ffff /* end */
16634 static const struct vec3 quad[] =
16636 {-1.0f, -1.0f, -0.5f},
16637 {-1.0f, 1.0f, -0.5f},
16638 { 1.0f, -1.0f, 1.5f},
16639 { 1.0f, 1.0f, 1.5f},
16641 static const D3DCOLOR expected[] =
16643 0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
16644 0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
16645 0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
16646 0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
16648 /* The Windows 8 testbot (WARP) appears to not clip z for regular
16649 * vertices either. */
16650 static const D3DCOLOR expected_broken[] =
16652 0x0020df20, 0x0060df60, 0x009fdf9f, 0x00dfdfdf,
16653 0x00209f20, 0x00609f60, 0x009f9f9f, 0x00df9fdf,
16654 0x00206020, 0x00606060, 0x009f609f, 0x00df60df,
16655 0x00202020, 0x00602060, 0x009f209f, 0x00df20df,
16658 IDirect3DVertexShader9 *vs;
16659 IDirect3DPixelShader9 *ps;
16661 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
16662 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16663 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
16664 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
16665 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
16666 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
16667 hr = IDirect3DDevice9_SetVertexShader(device, vs);
16668 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
16669 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16670 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
16672 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
16673 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16674 hr = IDirect3DDevice9_BeginScene(device);
16675 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16676 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16677 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16678 hr = IDirect3DDevice9_EndScene(device);
16679 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16681 for (i = 0; i < 4; ++i)
16683 for (j = 0; j < 4; ++j)
16685 x = 80 * ((2 * j) + 1);
16686 y = 60 * ((2 * i) + 1);
16687 color = getPixelColor(device, x, y);
16688 ok(color_match(color, expected[i * 4 + j], 1)
16689 || broken(color_match(color, expected_broken[i * 4 + j], 1)),
16690 "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
16694 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16695 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
16697 IDirect3DPixelShader9_Release(ps);
16698 IDirect3DVertexShader9_Release(vs);
16701 refcount = IDirect3DDevice9_Release(device);
16702 ok(!refcount, "Device has %u references left.\n", refcount);
16703 done:
16704 IDirect3D9_Release(d3d);
16705 DestroyWindow(window);
16708 static void fog_special_test(void)
16710 static const struct
16712 struct vec3 position;
16713 D3DCOLOR diffuse;
16715 quad[] =
16717 {{ -1.0f, -1.0f, 0.0f}, 0xff00ff00},
16718 {{ -1.0f, 1.0f, 0.0f}, 0xff00ff00},
16719 {{ 1.0f, -1.0f, 1.0f}, 0xff00ff00},
16720 {{ 1.0f, 1.0f, 1.0f}, 0xff00ff00}
16722 static const struct
16724 DWORD vertexmode, tablemode;
16725 BOOL vs, ps;
16726 D3DCOLOR color_left, color_right;
16728 tests[] =
16730 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, FALSE, 0x00ff0000, 0x00ff0000},
16731 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, TRUE, 0x00ff0000, 0x00ff0000},
16732 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, FALSE, 0x00ff0000, 0x00ff0000},
16733 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, TRUE, 0x00ff0000, 0x00ff0000},
16735 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, FALSE, 0x0000ff00, 0x00ff0000},
16736 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, TRUE, 0x0000ff00, 0x00ff0000},
16737 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, FALSE, 0x0000ff00, 0x00ff0000},
16738 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, TRUE, 0x0000ff00, 0x00ff0000},
16740 static const DWORD pixel_shader_code[] =
16742 0xffff0101, /* ps_1_1 */
16743 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
16744 0x0000ffff
16746 static const DWORD vertex_shader_code[] =
16748 0xfffe0101, /* vs_1_1 */
16749 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
16750 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
16751 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
16752 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
16753 0x0000ffff
16755 static const D3DMATRIX identity =
16757 1.0f, 0.0f, 0.0f, 0.0f,
16758 0.0f, 1.0f, 0.0f, 0.0f,
16759 0.0f, 0.0f, 1.0f, 0.0f,
16760 0.0f, 0.0f, 0.0f, 1.0f,
16761 }}};
16762 union
16764 float f;
16765 DWORD d;
16766 } conv;
16767 DWORD color;
16768 HRESULT hr;
16769 unsigned int i;
16770 IDirect3DPixelShader9 *ps;
16771 IDirect3DVertexShader9 *vs;
16772 IDirect3DDevice9 *device;
16773 IDirect3D9 *d3d;
16774 ULONG refcount;
16775 D3DCAPS9 caps;
16776 HWND window;
16778 window = create_window();
16779 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16780 ok(!!d3d, "Failed to create a D3D object.\n");
16781 if (!(device = create_device(d3d, window, window, TRUE)))
16783 skip("Failed to create a D3D device, skipping tests.\n");
16784 goto done;
16787 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16788 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
16789 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
16791 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code, &vs);
16792 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
16794 else
16796 skip("Vertex Shaders not supported, skipping some fog tests.\n");
16797 vs = NULL;
16799 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
16801 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &ps);
16802 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
16804 else
16806 skip("Pixel Shaders not supported, skipping some fog tests.\n");
16807 ps = NULL;
16810 /* The table fog tests seem to depend on the projection matrix explicitly
16811 * being set to an identity matrix, even though that's the default.
16812 * (AMD Radeon HD 6310, Windows 7) */
16813 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
16814 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
16816 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
16817 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16818 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16819 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
16820 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
16821 ok(SUCCEEDED(hr), "Failed to enable fog, hr %#x.\n", hr);
16822 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffff0000);
16823 ok(SUCCEEDED(hr), "Failed to set fog color, hr %#x.\n", hr);
16825 conv.f = 0.5f;
16826 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, conv.d);
16827 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#x.\n", hr);
16828 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, conv.d);
16829 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#x.\n", hr);
16831 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
16833 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
16834 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16836 if (!tests[i].vs)
16838 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
16839 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
16841 else if (vs)
16843 hr = IDirect3DDevice9_SetVertexShader(device, vs);
16844 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
16846 else
16848 continue;
16851 if (!tests[i].ps)
16853 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16854 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
16856 else if (ps)
16858 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16859 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
16861 else
16863 continue;
16866 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vertexmode);
16867 ok(SUCCEEDED(hr), "Failed to set fogvertexmode, hr %#x.\n", hr);
16868 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tablemode);
16869 ok(SUCCEEDED(hr), "Failed to set fogtablemode, hr %#x.\n", hr);
16871 hr = IDirect3DDevice9_BeginScene(device);
16872 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16873 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16874 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16875 hr = IDirect3DDevice9_EndScene(device);
16876 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16878 color = getPixelColor(device, 310, 240);
16879 ok(color_match(color, tests[i].color_left, 1),
16880 "Expected left color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_left, color, i);
16881 color = getPixelColor(device, 330, 240);
16882 ok(color_match(color, tests[i].color_right, 1),
16883 "Expected right color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_right, color, i);
16885 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16886 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
16889 if (vs)
16890 IDirect3DVertexShader9_Release(vs);
16891 if (ps)
16892 IDirect3DPixelShader9_Release(ps);
16893 refcount = IDirect3DDevice9_Release(device);
16894 ok(!refcount, "Device has %u references left.\n", refcount);
16895 done:
16896 IDirect3D9_Release(d3d);
16897 DestroyWindow(window);
16900 static void volume_srgb_test(void)
16902 HRESULT hr;
16903 unsigned int i, j;
16904 IDirect3DVolumeTexture9 *tex1, *tex2;
16905 D3DPOOL pool;
16906 D3DLOCKED_BOX locked_box;
16907 IDirect3DDevice9 *device;
16908 IDirect3D9 *d3d;
16909 D3DCOLOR color;
16910 ULONG refcount;
16911 HWND window;
16913 static const struct
16915 BOOL srgb;
16916 DWORD color;
16918 tests[] =
16920 /* Try toggling on and off */
16921 { FALSE, 0x007f7f7f },
16922 { TRUE, 0x00363636 },
16923 { FALSE, 0x007f7f7f },
16925 static const struct
16927 struct vec3 pos;
16928 struct vec3 texcrd;
16930 quad[] =
16932 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
16933 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
16934 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
16935 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
16938 window = create_window();
16939 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16940 ok(!!d3d, "Failed to create a D3D object.\n");
16941 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
16942 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_VOLUMETEXTURE, D3DFMT_A8R8G8B8) != D3D_OK)
16944 skip("D3DFMT_A8R8G8B8 volume textures with SRGBREAD not supported.\n");
16945 goto done;
16947 if (!(device = create_device(d3d, window, window, TRUE)))
16949 skip("Failed to create a D3D device, skipping tests.\n");
16950 goto done;
16953 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
16954 ok(SUCCEEDED(hr), "Failed to set color op 0, hr %#x.\n", hr);
16955 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
16956 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
16957 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
16958 ok(SUCCEEDED(hr), "Failed to set color op 0, hr %#x.\n", hr);
16959 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
16960 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
16962 for (i = 0; i < 2; i++)
16964 if (!i)
16965 pool = D3DPOOL_SYSTEMMEM;
16966 else
16967 pool = D3DPOOL_MANAGED;
16969 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, 0, D3DFMT_A8R8G8B8, pool, &tex1, NULL);
16970 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
16971 hr = IDirect3DVolumeTexture9_LockBox(tex1, 0, &locked_box, NULL, 0);
16972 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
16973 *((DWORD *)locked_box.pBits) = 0x7f7f7f7f;
16974 hr = IDirect3DVolumeTexture9_UnlockBox(tex1, 0);
16975 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
16977 if (!i)
16979 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, 0,
16980 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
16981 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
16982 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex1, (IDirect3DBaseTexture9 *)tex2);
16983 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16984 IDirect3DVolumeTexture9_Release(tex1);
16986 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex2);
16987 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16988 IDirect3DVolumeTexture9_Release(tex2);
16990 else
16992 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex1);
16993 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16994 IDirect3DVolumeTexture9_Release(tex1);
16997 for (j = 0; j < sizeof(tests) / sizeof(*tests); j++)
16999 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, tests[j].srgb);
17000 ok(SUCCEEDED(hr), "Failed to set srgb state, hr %#x.\n", hr);
17002 hr = IDirect3DDevice9_BeginScene(device);
17003 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17004 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17005 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17006 hr = IDirect3DDevice9_EndScene(device);
17007 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17009 color = getPixelColor(device, 320, 240);
17010 ok(color_match(color, tests[j].color, 2),
17011 "Expected color 0x%08x, got 0x%08x, i = %u, j = %u.\n", tests[j].color, color, i, j);
17013 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17014 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
17018 refcount = IDirect3DDevice9_Release(device);
17019 ok(!refcount, "Device has %u references left.\n", refcount);
17020 done:
17021 IDirect3D9_Release(d3d);
17022 DestroyWindow(window);
17025 static void volume_dxt5_test(void)
17027 IDirect3DVolumeTexture9 *texture;
17028 IDirect3DDevice9 *device;
17029 D3DLOCKED_BOX box;
17030 IDirect3D9 *d3d;
17031 unsigned int i;
17032 ULONG refcount;
17033 DWORD color;
17034 HWND window;
17035 HRESULT hr;
17037 static const char texture_data[] =
17039 /* A 8x4x2 texture consisting of 4 4x4 blocks. The colors of the blocks are red, green, blue and white. */
17040 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
17041 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
17042 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
17043 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
17045 static const struct
17047 struct vec3 position;
17048 struct vec3 texcrd;
17050 quads[] =
17052 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
17053 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
17054 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
17055 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
17057 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
17058 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
17059 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
17060 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
17062 static const DWORD expected_colors[] = {0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff};
17064 window = create_window();
17065 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17066 ok(!!d3d, "Failed to create a D3D object.\n");
17067 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17068 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_DXT5)))
17070 skip("DXT5 volume textures are not supported, skipping test.\n");
17071 goto done;
17073 if (!(device = create_device(d3d, window, window, TRUE)))
17075 skip("Failed to create a D3D device, skipping tests.\n");
17076 goto done;
17079 hr = IDirect3DDevice9_CreateVolumeTexture(device, 8, 4, 2, 1, 0, D3DFMT_DXT5,
17080 D3DPOOL_MANAGED, &texture, NULL);
17081 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
17083 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
17084 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
17085 memcpy(box.pBits, texture_data, sizeof(texture_data));
17086 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
17087 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
17089 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
17090 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
17091 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
17092 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17093 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17094 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17095 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
17096 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17097 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
17098 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17099 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
17100 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
17102 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
17103 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17104 hr = IDirect3DDevice9_BeginScene(device);
17105 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17106 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
17107 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17108 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
17109 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17110 hr = IDirect3DDevice9_EndScene(device);
17111 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17113 for (i = 0; i < 4; i++)
17115 color = getPixelColor(device, 80 + 160 * i, 240);
17116 ok (color_match(color, expected_colors[i], 1),
17117 "Expected color 0x%08x, got 0x%08x, case %u.\n", expected_colors[i], color, i);
17120 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17121 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17122 IDirect3DVolumeTexture9_Release(texture);
17123 refcount = IDirect3DDevice9_Release(device);
17124 ok(!refcount, "Device has %u references left.\n", refcount);
17125 done:
17126 IDirect3D9_Release(d3d);
17127 DestroyWindow(window);
17130 static void volume_v16u16_test(void)
17132 IDirect3DVolumeTexture9 *texture;
17133 IDirect3DPixelShader9 *shader;
17134 IDirect3DDevice9 *device;
17135 D3DLOCKED_BOX box;
17136 IDirect3D9 *d3d;
17137 unsigned int i;
17138 ULONG refcount;
17139 D3DCAPS9 caps;
17140 SHORT *texel;
17141 DWORD color;
17142 HWND window;
17143 HRESULT hr;
17145 static const struct
17147 struct vec3 position;
17148 struct vec3 texcrd;
17150 quads[] =
17152 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
17153 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
17154 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
17155 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
17157 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
17158 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
17159 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
17160 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
17162 static const DWORD shader_code[] =
17164 0xffff0101, /* ps_1_1 */
17165 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, */
17166 0x3f000000, 0x3f000000, /* 0.5, 0.5 */
17167 0x00000042, 0xb00f0000, /* tex t0 */
17168 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
17169 0x0000ffff /* end */
17172 window = create_window();
17173 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17174 ok(!!d3d, "Failed to create a D3D object.\n");
17175 if (!(device = create_device(d3d, window, window, TRUE)))
17177 skip("Failed to create a D3D device, skipping tests.\n");
17178 goto done;
17181 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17182 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17183 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
17185 skip("No ps_1_1 support, skipping tests.\n");
17186 IDirect3DDevice9_Release(device);
17187 goto done;
17189 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17190 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_V16U16)))
17192 skip("Volume V16U16 textures are not supported, skipping test.\n");
17193 IDirect3DDevice9_Release(device);
17194 goto done;
17197 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
17198 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
17199 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
17200 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
17201 hr = IDirect3DDevice9_SetPixelShader(device, shader);
17202 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
17203 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
17204 ok(SUCCEEDED(hr), "Failed to set filter, hr %#x.\n", hr);
17206 for (i = 0; i < 2; i++)
17208 D3DPOOL pool;
17210 if (i)
17211 pool = D3DPOOL_SYSTEMMEM;
17212 else
17213 pool = D3DPOOL_MANAGED;
17215 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
17216 pool, &texture, NULL);
17217 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
17219 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
17220 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
17222 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 0 * box.SlicePitch);
17223 texel[0] = 32767;
17224 texel[1] = 32767;
17225 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 0 * box.SlicePitch);
17226 texel[0] = -32768;
17227 texel[1] = 0;
17228 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 1 * box.SlicePitch);
17229 texel[0] = -16384;
17230 texel[1] = 16384;
17231 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 1 * box.SlicePitch);
17232 texel[0] = 0;
17233 texel[1] = 0;
17235 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
17236 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
17238 if (i)
17240 IDirect3DVolumeTexture9 *texture2;
17242 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
17243 D3DPOOL_DEFAULT, &texture2, NULL);
17244 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
17246 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture,
17247 (IDirect3DBaseTexture9 *)texture2);
17248 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17250 IDirect3DVolumeTexture9_Release(texture);
17251 texture = texture2;
17254 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
17255 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17257 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
17258 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17259 hr = IDirect3DDevice9_BeginScene(device);
17260 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17261 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
17262 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17263 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
17264 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17265 hr = IDirect3DDevice9_EndScene(device);
17266 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17268 color = getPixelColor(device, 120, 160);
17269 ok (color_match(color, 0x000080ff, 2),
17270 "Expected color 0x000080ff, got 0x%08x, V16U16 input -32768, 0.\n", color);
17271 color = getPixelColor(device, 120, 400);
17272 ok (color_match(color, 0x00ffffff, 2),
17273 "Expected color 0x00ffffff, got 0x%08x, V16U16 input 32767, 32767.\n", color);
17274 color = getPixelColor(device, 360, 160);
17275 ok (color_match(color, 0x007f7fff, 2),
17276 "Expected color 0x007f7fff, got 0x%08x, V16U16 input 0, 0.\n", color);
17277 color = getPixelColor(device, 360, 400);
17278 ok (color_match(color, 0x0040c0ff, 2),
17279 "Expected color 0x0040c0ff, got 0x%08x, V16U16 input -16384, 16384.\n", color);
17281 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17282 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17284 IDirect3DVolumeTexture9_Release(texture);
17287 IDirect3DPixelShader9_Release(shader);
17288 refcount = IDirect3DDevice9_Release(device);
17289 ok(!refcount, "Device has %u references left.\n", refcount);
17290 done:
17291 IDirect3D9_Release(d3d);
17292 DestroyWindow(window);
17295 static void add_dirty_rect_test_draw(IDirect3DDevice9 *device)
17297 HRESULT hr;
17298 static const struct
17300 struct vec3 position;
17301 struct vec2 texcoord;
17303 quad[] =
17305 {{-1.0, -1.0, 0.0}, {0.0, 0.0}},
17306 {{-1.0, 1.0, 0.0}, {0.0, 1.0}},
17307 {{ 1.0, -1.0, 0.0}, {1.0, 0.0}},
17308 {{ 1.0, 1.0, 0.0}, {1.0, 1.0}},
17311 hr = IDirect3DDevice9_BeginScene(device);
17312 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17313 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad, sizeof(*quad));
17314 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17315 hr = IDirect3DDevice9_EndScene(device);
17316 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17319 static void add_dirty_rect_test(void)
17321 HRESULT hr;
17322 IDirect3DTexture9 *tex_dst1, *tex_dst2, *tex_src_red, *tex_src_green,
17323 *tex_managed, *tex_dynamic;
17324 IDirect3DSurface9 *surface_dst2, *surface_src_green, *surface_src_red,
17325 *surface_managed, *surface_dynamic;
17326 IDirect3DDevice9 *device;
17327 IDirect3D9 *d3d;
17328 unsigned int i;
17329 ULONG refcount;
17330 DWORD *texel;
17331 HWND window;
17332 D3DLOCKED_RECT locked_rect;
17333 static const RECT part_rect = {96, 96, 160, 160};
17334 DWORD color;
17336 window = create_window();
17337 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17338 ok(!!d3d, "Failed to create a D3D object.\n");
17339 if (!(device = create_device(d3d, window, window, TRUE)))
17341 skip("Failed to create a D3D device, skipping tests.\n");
17342 IDirect3D9_Release(d3d);
17343 DestroyWindow(window);
17344 return;
17347 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17348 D3DPOOL_DEFAULT, &tex_dst1, NULL);
17349 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17350 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17351 D3DPOOL_DEFAULT, &tex_dst2, NULL);
17352 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17353 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17354 D3DPOOL_SYSTEMMEM, &tex_src_red, NULL);
17355 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17356 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17357 D3DPOOL_SYSTEMMEM, &tex_src_green, NULL);
17358 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17359 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17360 D3DPOOL_MANAGED, &tex_managed, NULL);
17361 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17362 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, D3DUSAGE_DYNAMIC,
17363 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex_dynamic, NULL);
17364 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17366 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dst2, 0, &surface_dst2);
17367 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17368 hr = IDirect3DTexture9_GetSurfaceLevel(tex_src_green, 0, &surface_src_green);
17369 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17370 hr = IDirect3DTexture9_GetSurfaceLevel(tex_src_red, 0, &surface_src_red);
17371 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17372 hr = IDirect3DTexture9_GetSurfaceLevel(tex_managed, 0, &surface_managed);
17373 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17374 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dynamic, 0, &surface_dynamic);
17375 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17377 fill_surface(surface_src_red, 0x00ff0000, 0);
17378 fill_surface(surface_src_green, 0x0000ff00, 0);
17380 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
17381 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
17382 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17383 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17384 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
17385 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17387 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17388 (IDirect3DBaseTexture9 *)tex_dst1);
17389 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17391 /* The second UpdateTexture call writing to tex_dst2 is ignored because tex_src_green is not dirty. */
17392 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_red,
17393 (IDirect3DBaseTexture9 *)tex_dst2);
17394 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17395 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17396 (IDirect3DBaseTexture9 *)tex_dst2);
17397 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17399 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst1);
17400 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17401 add_dirty_rect_test_draw(device);
17402 color = getPixelColor(device, 320, 240);
17403 ok(color_match(color, 0x0000ff00, 1),
17404 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17405 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17406 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17408 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst2);
17409 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17410 add_dirty_rect_test_draw(device);
17411 color = getPixelColor(device, 320, 240);
17412 todo_wine ok(color_match(color, 0x00ff0000, 1),
17413 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17414 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17415 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17417 /* AddDirtyRect on the destination is ignored. */
17418 hr = IDirect3DTexture9_AddDirtyRect(tex_dst2, &part_rect);
17419 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17420 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17421 (IDirect3DBaseTexture9 *)tex_dst2);
17422 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17423 add_dirty_rect_test_draw(device);
17424 color = getPixelColor(device, 320, 240);
17425 todo_wine ok(color_match(color, 0x00ff0000, 1),
17426 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17427 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17428 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17430 hr = IDirect3DTexture9_AddDirtyRect(tex_dst2, NULL);
17431 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17432 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17433 (IDirect3DBaseTexture9 *)tex_dst2);
17434 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17435 add_dirty_rect_test_draw(device);
17436 color = getPixelColor(device, 320, 240);
17437 todo_wine ok(color_match(color, 0x00ff0000, 1),
17438 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17439 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17440 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17442 /* AddDirtyRect on the source makes UpdateTexture work. Partial rectangle
17443 * tracking is supported. */
17444 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, &part_rect);
17445 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17446 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17447 (IDirect3DBaseTexture9 *)tex_dst2);
17448 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17449 add_dirty_rect_test_draw(device);
17450 color = getPixelColor(device, 320, 240);
17451 ok(color_match(color, 0x0000ff00, 1),
17452 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17453 color = getPixelColor(device, 1, 1);
17454 todo_wine ok(color_match(color, 0x00ff0000, 1),
17455 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17456 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17457 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17459 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, NULL);
17460 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17461 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17462 (IDirect3DBaseTexture9 *)tex_dst2);
17463 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17464 add_dirty_rect_test_draw(device);
17465 color = getPixelColor(device, 1, 1);
17466 ok(color_match(color, 0x0000ff00, 1),
17467 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17469 /* Locks with NO_DIRTY_UPDATE are ignored. */
17470 fill_surface(surface_src_green, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE);
17471 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17472 (IDirect3DBaseTexture9 *)tex_dst2);
17473 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17474 add_dirty_rect_test_draw(device);
17475 color = getPixelColor(device, 320, 240);
17476 todo_wine ok(color_match(color, 0x0000ff00, 1),
17477 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17478 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17479 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17481 /* Readonly maps write to D3DPOOL_SYSTEMMEM, but don't record a dirty rectangle. */
17482 fill_surface(surface_src_green, 0x000000ff, D3DLOCK_READONLY);
17483 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17484 (IDirect3DBaseTexture9 *)tex_dst2);
17485 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17486 add_dirty_rect_test_draw(device);
17487 color = getPixelColor(device, 320, 240);
17488 todo_wine ok(color_match(color, 0x0000ff00, 1),
17489 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17490 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17491 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17493 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, NULL);
17494 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17495 (IDirect3DBaseTexture9 *)tex_dst2);
17496 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17497 add_dirty_rect_test_draw(device);
17498 color = getPixelColor(device, 320, 240);
17499 ok(color_match(color, 0x000000ff, 1),
17500 "Expected color 0x000000ff, got 0x%08x.\n", color);
17501 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17502 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17504 /* Maps without either of these flags record a dirty rectangle. */
17505 fill_surface(surface_src_green, 0x00ffffff, 0);
17506 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17507 (IDirect3DBaseTexture9 *)tex_dst2);
17508 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17509 add_dirty_rect_test_draw(device);
17510 color = getPixelColor(device, 320, 240);
17511 ok(color_match(color, 0x00ffffff, 1),
17512 "Expected color 0x00ffffff, got 0x%08x.\n", color);
17513 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17514 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17516 /* Partial LockRect works just like a partial AddDirtyRect call. */
17517 hr = IDirect3DTexture9_LockRect(tex_src_green, 0, &locked_rect, &part_rect, 0);
17518 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17519 texel = locked_rect.pBits;
17520 for (i = 0; i < 64; i++)
17521 texel[i] = 0x00ff00ff;
17522 for (i = 1; i < 64; i++)
17523 memcpy((BYTE *)locked_rect.pBits + i * locked_rect.Pitch, locked_rect.pBits, locked_rect.Pitch);
17524 hr = IDirect3DTexture9_UnlockRect(tex_src_green, 0);
17525 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17526 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17527 (IDirect3DBaseTexture9 *)tex_dst2);
17528 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17529 add_dirty_rect_test_draw(device);
17530 color = getPixelColor(device, 320, 240);
17531 ok(color_match(color, 0x00ff00ff, 1),
17532 "Expected color 0x00ff00ff, got 0x%08x.\n", color);
17533 color = getPixelColor(device, 1, 1);
17534 ok(color_match(color, 0x00ffffff, 1),
17535 "Expected color 0x00ffffff, got 0x%08x.\n", color);
17536 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17537 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17539 fill_surface(surface_src_red, 0x00ff0000, 0);
17540 fill_surface(surface_src_green, 0x0000ff00, 0);
17542 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17543 (IDirect3DBaseTexture9 *)tex_dst1);
17544 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17545 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst1);
17546 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17547 add_dirty_rect_test_draw(device);
17548 color = getPixelColor(device, 320, 240);
17549 ok(color_match(color, 0x0000ff00, 1),
17550 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17551 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17552 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17554 /* UpdateSurface ignores the missing dirty marker. */
17555 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_red,
17556 (IDirect3DBaseTexture9 *)tex_dst2);
17557 hr = IDirect3DDevice9_UpdateSurface(device, surface_src_green, NULL, surface_dst2, NULL);
17558 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
17559 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst2);
17560 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17561 add_dirty_rect_test_draw(device);
17562 color = getPixelColor(device, 320, 240);
17563 ok(color_match(color, 0x0000ff00, 1),
17564 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17565 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17566 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17568 /* Tests with managed textures. */
17569 fill_surface(surface_managed, 0x00ff0000, 0);
17570 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_managed);
17571 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17572 add_dirty_rect_test_draw(device);
17573 color = getPixelColor(device, 320, 240);
17574 ok(color_match(color, 0x00ff0000, 1),
17575 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17576 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17577 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17579 /* Managed textures also honor D3DLOCK_NO_DIRTY_UPDATE. */
17580 fill_surface(surface_managed, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE);
17581 add_dirty_rect_test_draw(device);
17582 color = getPixelColor(device, 320, 240);
17583 ok(color_match(color, 0x00ff0000, 1),
17584 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17585 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17586 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17588 /* AddDirtyRect uploads the new contents.
17589 * Side note, not tested in the test: Partial surface updates work, and two separate
17590 * dirty rectangles are tracked individually. Tested on Nvidia Kepler, other drivers
17591 * untested. */
17592 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
17593 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17594 add_dirty_rect_test_draw(device);
17595 color = getPixelColor(device, 320, 240);
17596 ok(color_match(color, 0x0000ff00, 1),
17597 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17598 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17599 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17601 /* So does EvictManagedResources. */
17602 fill_surface(surface_managed, 0x000000ff, D3DLOCK_NO_DIRTY_UPDATE);
17603 hr = IDirect3DDevice9_EvictManagedResources(device);
17604 ok(SUCCEEDED(hr), "Failed to evict managed resources, hr %#x.\n", hr);
17605 add_dirty_rect_test_draw(device);
17606 color = getPixelColor(device, 320, 240);
17607 ok(color_match(color, 0x000000ff, 1),
17608 "Expected color 0x000000ff, got 0x%08x.\n", color);
17609 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17610 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17612 /* Tests with dynamic textures */
17613 fill_surface(surface_dynamic, 0x0000ffff, 0);
17614 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dynamic);
17615 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17616 add_dirty_rect_test_draw(device);
17617 color = getPixelColor(device, 320, 240);
17618 ok(color_match(color, 0x0000ffff, 1),
17619 "Expected color 0x0000ffff, got 0x%08x.\n", color);
17620 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17621 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17623 /* Dynamic textures don't honor D3DLOCK_NO_DIRTY_UPDATE. */
17624 fill_surface(surface_dynamic, 0x00ffff00, D3DLOCK_NO_DIRTY_UPDATE);
17625 add_dirty_rect_test_draw(device);
17626 color = getPixelColor(device, 320, 240);
17627 ok(color_match(color, 0x00ffff00, 1),
17628 "Expected color 0x00ffff00, got 0x%08x.\n", color);
17629 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17630 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17632 /* AddDirtyRect on a locked texture is allowed. */
17633 hr = IDirect3DTexture9_LockRect(tex_src_red, 0, &locked_rect, NULL, 0);
17634 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17635 hr = IDirect3DTexture9_AddDirtyRect(tex_src_red, NULL);
17636 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17637 hr = IDirect3DTexture9_UnlockRect(tex_src_red, 0);
17638 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17640 /* Redundant AddDirtyRect calls are ok. */
17641 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
17642 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17643 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
17644 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17646 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
17647 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17648 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
17649 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17650 IDirect3DSurface9_Release(surface_dst2);
17651 IDirect3DSurface9_Release(surface_managed);
17652 IDirect3DSurface9_Release(surface_src_red);
17653 IDirect3DSurface9_Release(surface_src_green);
17654 IDirect3DSurface9_Release(surface_dynamic);
17655 IDirect3DTexture9_Release(tex_src_red);
17656 IDirect3DTexture9_Release(tex_src_green);
17657 IDirect3DTexture9_Release(tex_dst1);
17658 IDirect3DTexture9_Release(tex_dst2);
17659 IDirect3DTexture9_Release(tex_managed);
17660 IDirect3DTexture9_Release(tex_dynamic);
17661 refcount = IDirect3DDevice9_Release(device);
17662 ok(!refcount, "Device has %u references left.\n", refcount);
17663 IDirect3D9_Release(d3d);
17664 DestroyWindow(window);
17667 static void test_per_stage_constant(void)
17669 IDirect3DDevice9 *device;
17670 IDirect3D9 *d3d;
17671 D3DCOLOR color;
17672 ULONG refcount;
17673 D3DCAPS9 caps;
17674 HWND window;
17675 HRESULT hr;
17677 static const struct
17679 struct vec3 position;
17680 D3DCOLOR diffuse;
17682 quad[] =
17684 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
17685 {{-1.0f, 1.0f, 0.1f}, 0xffff0000},
17686 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
17687 {{ 1.0f, 1.0f, 0.1f}, 0xffff0000},
17690 window = create_window();
17691 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17692 ok(!!d3d, "Failed to create a D3D object.\n");
17693 if (!(device = create_device(d3d, window, window, TRUE)))
17695 skip("Failed to create a D3D device, skipping tests.\n");
17696 goto done;
17699 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17700 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17701 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_PERSTAGECONSTANT))
17703 skip("Per-stage constants not supported, skipping tests.\n");
17704 IDirect3DDevice9_Release(device);
17705 goto done;
17708 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
17709 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
17710 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
17711 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17712 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
17713 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17714 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
17715 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17716 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
17717 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17719 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_CONSTANT, 0x80a1b2c3);
17720 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17721 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT);
17722 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17723 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17724 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17726 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17727 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17729 hr = IDirect3DDevice9_BeginScene(device);
17730 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17731 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17732 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17733 hr = IDirect3DDevice9_EndScene(device);
17734 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17736 color = getPixelColor(device, 320, 240);
17737 ok(color_match(color, 0x00a1b2c3, 1), "Got unexpected color 0x%08x.\n", color);
17738 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17739 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17741 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT | D3DTA_COMPLEMENT);
17742 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17744 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17745 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17747 hr = IDirect3DDevice9_BeginScene(device);
17748 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17749 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17750 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17751 hr = IDirect3DDevice9_EndScene(device);
17752 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17754 color = getPixelColor(device, 320, 240);
17755 ok(color_match(color, 0x005e4d3c, 1), "Got unexpected color 0x%08x.\n", color);
17756 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17757 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17759 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT | D3DTA_ALPHAREPLICATE);
17760 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17762 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17763 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17765 hr = IDirect3DDevice9_BeginScene(device);
17766 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17767 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17768 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17769 hr = IDirect3DDevice9_EndScene(device);
17770 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17772 color = getPixelColor(device, 320, 240);
17773 ok(color_match(color, 0x00808080, 1), "Got unexpected color 0x%08x.\n", color);
17774 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17775 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17777 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_CONSTANT);
17778 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17779 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
17780 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17781 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CURRENT);
17782 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17784 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17785 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17787 hr = IDirect3DDevice9_BeginScene(device);
17788 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17789 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17790 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17791 hr = IDirect3DDevice9_EndScene(device);
17792 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17794 color = getPixelColor(device, 320, 240);
17795 ok(color_match(color, 0x0080007f, 1), "Got unexpected color 0x%08x.\n", color);
17796 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17797 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17799 refcount = IDirect3DDevice9_Release(device);
17800 ok(!refcount, "Device has %u references left.\n", refcount);
17801 done:
17802 IDirect3D9_Release(d3d);
17803 DestroyWindow(window);
17806 static void test_3dc_formats(void)
17808 static const char ati1n_data[] =
17810 /* A 4x4 texture with the color component at 50%. */
17811 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
17813 static const char ati2n_data[] =
17815 /* A 8x4 texture consisting of 2 4x4 blocks. The first block has 50% first color component,
17816 * 0% second component. Second block is the opposite. */
17817 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
17818 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
17820 static const struct
17822 struct vec3 position;
17823 struct vec2 texcoord;
17825 quads[] =
17827 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
17828 {{-1.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
17829 {{ 0.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
17830 {{ 0.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
17832 {{ 0.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
17833 {{ 0.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
17834 {{ 1.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
17835 {{ 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
17837 static const DWORD ati1n_fourcc = MAKEFOURCC('A','T','I','1');
17838 static const DWORD ati2n_fourcc = MAKEFOURCC('A','T','I','2');
17839 static const struct
17841 struct vec2 position;
17842 D3DCOLOR amd_r500;
17843 D3DCOLOR amd_r600;
17844 D3DCOLOR nvidia_old;
17845 D3DCOLOR nvidia_new;
17847 expected_colors[] =
17849 {{ 80, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
17850 {{240, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
17851 {{400, 240}, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff},
17852 {{560, 240}, 0x007f00ff, 0x007f00ff, 0x007f00ff, 0x007f00ff},
17854 IDirect3D9 *d3d;
17855 IDirect3DDevice9 *device;
17856 IDirect3DTexture9 *ati1n_texture, *ati2n_texture;
17857 D3DCAPS9 caps;
17858 D3DLOCKED_RECT rect;
17859 D3DCOLOR color;
17860 ULONG refcount;
17861 HWND window;
17862 HRESULT hr;
17863 unsigned int i;
17865 window = create_window();
17866 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17867 ok(!!d3d, "Failed to create a D3D object.\n");
17868 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17869 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati1n_fourcc)))
17871 skip("ATI1N textures are not supported, skipping test.\n");
17872 goto done;
17874 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17875 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati2n_fourcc)))
17877 skip("ATI2N textures are not supported, skipping test.\n");
17878 goto done;
17880 if (!(device = create_device(d3d, window, window, TRUE)))
17882 skip("Failed to create a D3D device, skipping tests.\n");
17883 goto done;
17885 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17886 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17887 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
17889 skip("D3DTA_TEMP not supported, skipping tests.\n");
17890 IDirect3DDevice9_Release(device);
17891 goto done;
17894 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, ati1n_fourcc,
17895 D3DPOOL_MANAGED, &ati1n_texture, NULL);
17896 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17898 hr = IDirect3DTexture9_LockRect(ati1n_texture, 0, &rect, NULL, 0);
17899 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17900 memcpy(rect.pBits, ati1n_data, sizeof(ati1n_data));
17901 hr = IDirect3DTexture9_UnlockRect(ati1n_texture, 0);
17902 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17904 hr = IDirect3DDevice9_CreateTexture(device, 8, 4, 1, 0, ati2n_fourcc,
17905 D3DPOOL_MANAGED, &ati2n_texture, NULL);
17906 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17908 hr = IDirect3DTexture9_LockRect(ati2n_texture, 0, &rect, NULL, 0);
17909 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17910 memcpy(rect.pBits, ati2n_data, sizeof(ati2n_data));
17911 hr = IDirect3DTexture9_UnlockRect(ati2n_texture, 0);
17912 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17914 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0));
17915 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
17916 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
17917 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17918 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
17919 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17920 /* The temporary register is initialized to 0. */
17921 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TEMP);
17922 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17923 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
17924 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#x.\n", hr);
17925 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
17926 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#x.\n", hr);
17927 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
17928 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17929 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
17930 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
17932 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
17933 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17934 hr = IDirect3DDevice9_BeginScene(device);
17935 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17936 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)ati1n_texture);
17937 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17938 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
17939 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17940 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)ati2n_texture);
17941 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17942 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
17943 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17944 hr = IDirect3DDevice9_EndScene(device);
17945 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17947 for (i = 0; i < 4; ++i)
17949 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
17950 ok (color_match(color, expected_colors[i].amd_r500, 1)
17951 || color_match(color, expected_colors[i].amd_r600, 1)
17952 || color_match(color, expected_colors[i].nvidia_old, 1)
17953 || color_match(color, expected_colors[i].nvidia_new, 1),
17954 "Got unexpected color 0x%08x, case %u.\n", color, i);
17957 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17958 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17959 IDirect3DTexture9_Release(ati2n_texture);
17960 IDirect3DTexture9_Release(ati1n_texture);
17961 refcount = IDirect3DDevice9_Release(device);
17962 ok(!refcount, "Device has %u references left.\n", refcount);
17964 done:
17965 IDirect3D9_Release(d3d);
17966 DestroyWindow(window);
17969 static void test_fog_interpolation(void)
17971 HRESULT hr;
17972 IDirect3DDevice9 *device;
17973 IDirect3D9 *d3d;
17974 ULONG refcount;
17975 HWND window;
17976 D3DCOLOR color;
17977 static const struct
17979 struct vec3 position;
17980 D3DCOLOR diffuse;
17981 D3DCOLOR specular;
17983 quad[] =
17985 {{-1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff000000},
17986 {{-1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff000000},
17987 {{ 1.0f, -1.0f, 1.0f}, 0xffff0000, 0x00000000},
17988 {{ 1.0f, 1.0f, 1.0f}, 0xffff0000, 0x00000000},
17990 union
17992 DWORD d;
17993 float f;
17994 } conv;
17995 unsigned int i;
17996 static const struct
17998 D3DFOGMODE vfog, tfog;
17999 D3DSHADEMODE shade;
18000 D3DCOLOR middle_color;
18001 BOOL todo;
18003 tests[] =
18005 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, FALSE},
18006 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, FALSE},
18007 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, TRUE},
18008 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, TRUE},
18009 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
18010 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
18011 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
18012 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
18014 static const D3DMATRIX ident_mat =
18016 1.0f, 0.0f, 0.0f, 0.0f,
18017 0.0f, 1.0f, 0.0f, 0.0f,
18018 0.0f, 0.0f, 1.0f, 0.0f,
18019 0.0f, 0.0f, 0.0f, 1.0f
18020 }}};
18021 D3DCAPS9 caps;
18023 window = create_window();
18024 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18025 ok(!!d3d, "Failed to create a D3D object.\n");
18027 if (!(device = create_device(d3d, window, window, TRUE)))
18029 skip("Failed to create a D3D device, skipping tests.\n");
18030 IDirect3D9_Release(d3d);
18031 DestroyWindow(window);
18032 return;
18035 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18036 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18037 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
18038 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
18040 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
18041 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
18042 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18043 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18044 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
18045 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18046 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
18047 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18048 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
18049 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18050 conv.f = 5.0;
18051 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGDENSITY, conv.d);
18052 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18054 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
18055 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
18056 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
18057 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
18058 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x000000ff);
18059 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18061 /* Some of the tests seem to depend on the projection matrix explicitly
18062 * being set to an identity matrix, even though that's the default.
18063 * (AMD Radeon X1600, AMD Radeon HD 6310, Windows 7). Without this,
18064 * the drivers seem to use a static z = 1.0 input for the fog equation.
18065 * The input value is independent of the actual z and w component of
18066 * the vertex position. */
18067 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
18068 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
18070 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
18072 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
18073 continue;
18075 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00808080, 0.0f, 0);
18076 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18078 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shade);
18079 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18080 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
18081 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18082 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
18083 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18084 hr = IDirect3DDevice9_BeginScene(device);
18085 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18086 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18087 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18088 hr = IDirect3DDevice9_EndScene(device);
18089 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18091 color = getPixelColor(device, 0, 240);
18092 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
18093 color = getPixelColor(device, 320, 240);
18094 todo_wine_if (tests[i].todo)
18095 ok(color_match(color, tests[i].middle_color, 2),
18096 "Got unexpected color 0x%08x, case %u.\n", color, i);
18097 color = getPixelColor(device, 639, 240);
18098 ok(color_match(color, 0x0000fd02, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
18099 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18100 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18103 refcount = IDirect3DDevice9_Release(device);
18104 ok(!refcount, "Device has %u references left.\n", refcount);
18105 IDirect3D9_Release(d3d);
18106 DestroyWindow(window);
18109 static void test_negative_fixedfunction_fog(void)
18111 HRESULT hr;
18112 IDirect3DDevice9 *device;
18113 IDirect3D9 *d3d;
18114 ULONG refcount;
18115 HWND window;
18116 D3DCOLOR color;
18117 static const struct
18119 struct vec3 position;
18120 D3DCOLOR diffuse;
18122 quad[] =
18124 {{-1.0f, -1.0f, -0.5f}, 0xffff0000},
18125 {{-1.0f, 1.0f, -0.5f}, 0xffff0000},
18126 {{ 1.0f, -1.0f, -0.5f}, 0xffff0000},
18127 {{ 1.0f, 1.0f, -0.5f}, 0xffff0000},
18129 static const struct
18131 struct vec4 position;
18132 D3DCOLOR diffuse;
18134 tquad[] =
18136 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
18137 {{640.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
18138 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
18139 {{640.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
18141 unsigned int i;
18142 static const D3DMATRIX zero =
18144 1.0f, 0.0f, 0.0f, 0.0f,
18145 0.0f, 1.0f, 0.0f, 0.0f,
18146 0.0f, 0.0f, 0.0f, 0.0f,
18147 0.0f, 0.0f, 0.0f, 1.0f
18148 }}};
18149 /* Needed to make AMD drivers happy. Yeah, it is not supposed to
18150 * have an effect on RHW draws. */
18151 static const D3DMATRIX identity =
18153 1.0f, 0.0f, 0.0f, 0.0f,
18154 0.0f, 1.0f, 0.0f, 0.0f,
18155 0.0f, 0.0f, 1.0f, 0.0f,
18156 0.0f, 0.0f, 0.0f, 1.0f
18157 }}};
18158 static const struct
18160 DWORD pos_type;
18161 const void *quad;
18162 size_t stride;
18163 const D3DMATRIX *matrix;
18164 union
18166 float f;
18167 DWORD d;
18168 } start, end;
18169 D3DFOGMODE vfog, tfog;
18170 DWORD color, color_broken, color_broken2;
18172 tests[] =
18174 /* Run the XYZRHW tests first. Depth clamping is broken after RHW draws on the testbot.
18176 * Geforce8+ GPUs on Windows abs() table fog, everything else does not. */
18177 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, { 0.0f}, {1.0f},
18178 D3DFOG_NONE, D3DFOG_LINEAR, 0x00ff0000, 0x00808000, 0x00808000},
18179 /* r200 GPUs and presumably all d3d8 and older HW clamp the fog
18180 * parameters to 0.0 and 1.0 in the table fog case. */
18181 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, {-1.0f}, {0.0f},
18182 D3DFOG_NONE, D3DFOG_LINEAR, 0x00808000, 0x00ff0000, 0x0000ff00},
18183 /* test_fog_interpolation shows that vertex fog evaluates the fog
18184 * equation in the vertex pipeline. Start = -1.0 && end = 0.0 shows
18185 * that the abs happens before the fog equation is evaluated.
18187 * Vertex fog abs() behavior is the same on all GPUs. */
18188 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
18189 D3DFOG_LINEAR, D3DFOG_NONE, 0x00808000, 0x00808000, 0x00808000},
18190 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, {-1.0f}, {0.0f},
18191 D3DFOG_LINEAR, D3DFOG_NONE, 0x0000ff00, 0x0000ff00, 0x0000ff00},
18192 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
18193 D3DFOG_EXP, D3DFOG_NONE, 0x009b6400, 0x009b6400, 0x009b6400},
18195 D3DCAPS9 caps;
18197 window = create_window();
18198 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18199 ok(!!d3d, "Failed to create a D3D object.\n");
18201 if (!(device = create_device(d3d, window, window, TRUE)))
18203 skip("Failed to create a D3D device, skipping tests.\n");
18204 IDirect3D9_Release(d3d);
18205 DestroyWindow(window);
18206 return;
18209 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18210 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18211 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
18212 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests.\n");
18214 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18215 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18216 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
18217 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18218 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
18219 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18220 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
18221 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18222 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
18223 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
18225 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
18227 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
18228 continue;
18230 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
18231 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18233 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, tests[i].matrix);
18234 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
18235 hr = IDirect3DDevice9_SetFVF(device, tests[i].pos_type | D3DFVF_DIFFUSE);
18236 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
18237 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, tests[i].start.d);
18238 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18239 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, tests[i].end.d);
18240 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18241 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
18242 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18243 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
18244 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18246 hr = IDirect3DDevice9_BeginScene(device);
18247 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18248 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tests[i].quad, tests[i].stride);
18249 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18250 hr = IDirect3DDevice9_EndScene(device);
18251 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18253 color = getPixelColor(device, 320, 240);
18254 ok(color_match(color, tests[i].color, 2) || broken(color_match(color, tests[i].color_broken, 2))
18255 || broken(color_match(color, tests[i].color_broken2, 2)),
18256 "Got unexpected color 0x%08x, case %u.\n", color, i);
18257 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18258 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18261 refcount = IDirect3DDevice9_Release(device);
18262 ok(!refcount, "Device has %u references left.\n", refcount);
18263 IDirect3D9_Release(d3d);
18264 DestroyWindow(window);
18267 static void test_position_index(void)
18269 static const D3DVERTEXELEMENT9 decl_elements[] =
18271 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
18272 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 1},
18273 D3DDECL_END()
18275 /* Declaring (and using) a position1 output semantic in a VS fails at draw time on AMD
18276 * but works on Nvidia.
18277 * MSDN is not consistent on this point. */
18278 static const DWORD vs_code[] =
18280 0xfffe0300, /* vs_3_0 */
18281 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
18282 0x0200001f, 0x80010000, 0x900f0001, /* dcl_position1 v1 */
18283 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position0 o0 */
18284 0x0200001f, 0x80010000, 0xe00f0001, /* dcl_position1 o1 */
18285 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
18286 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
18287 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
18288 0x02000001, 0xe00f0002, 0x90e40001, /* mov o2, v1 */
18289 0x0000ffff /* end */
18291 static const DWORD vs_code_2[] =
18293 0xfffe0300, /* vs_3_0 */
18294 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
18295 0x0200001f, 0x80010000, 0x900f0001, /* dcl_position1 v1 */
18296 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position0 o0 */
18297 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
18298 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
18299 0x02000001, 0xe00f0002, 0x90e40001, /* mov o2, v1 */
18300 0x0000ffff /* end */
18302 static const DWORD ps_code[] =
18304 0xffff0300, /* ps_3_0 */
18305 0x0200001f, 0x80010000, 0x900f0000, /* dcl_position1 v0 */
18306 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
18307 0x0000ffff /* end */
18309 static const DWORD ps_code_2[] =
18311 0xffff0300, /* ps_3_0 */
18312 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
18313 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
18314 0x0000ffff /* end */
18316 /* This one is considered invalid by the native shader assembler. */
18317 static const DWORD ps_code_bad[] =
18319 0xffff0300, /* ps_3_0 */
18320 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
18321 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
18322 0x0000ffff /* end */
18324 static const struct
18326 struct vec3 position;
18327 struct vec3 position1;
18329 quad[] =
18331 {{-1.0f, -1.0f, 0.5f}, {1.0f, 0.0f, 0.0f}},
18332 {{-1.0f, 1.0f, 0.5f}, {1.0f, 0.0f, 0.0f}},
18333 {{ 1.0f, -1.0f, 0.5f}, {0.0f, 1.0f, 0.0f}},
18334 {{ 1.0f, 1.0f, 0.5f}, {0.0f, 1.0f, 0.0f}},
18336 static const struct
18338 struct vec2 position;
18339 D3DCOLOR expected_color;
18340 D3DCOLOR broken_color;
18342 expected_colors[] =
18344 {{ 80, 240}, 0x00df2000, 0x00ff00ff},
18345 {{240, 240}, 0x009f6000, 0x00ff00ff},
18346 {{400, 240}, 0x00609f00, 0x00ff00ff},
18347 {{560, 240}, 0x0020df00, 0x00ff00ff},
18349 IDirect3D9 *d3d;
18350 IDirect3DDevice9 *device;
18351 IDirect3DVertexDeclaration9 *vertex_declaration;
18352 IDirect3DVertexShader9 *vs, *vs2;
18353 IDirect3DPixelShader9 *ps, *ps2;
18354 D3DCAPS9 caps;
18355 D3DCOLOR color;
18356 ULONG refcount;
18357 HWND window;
18358 HRESULT hr;
18359 unsigned int i;
18361 window = create_window();
18362 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18363 ok(!!d3d, "Failed to create a D3D object.\n");
18364 if (!(device = create_device(d3d, window, window, TRUE)))
18366 skip("Failed to create a D3D device, skipping tests.\n");
18367 goto done;
18370 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18371 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18372 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0)
18373 || caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
18375 skip("Shader model 3.0 unsupported, skipping tests.\n");
18376 IDirect3DDevice9_Release(device);
18377 goto done;
18380 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
18381 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed, hr %#x\n", hr);
18383 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
18384 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x\n", hr);
18386 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
18387 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
18388 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code_2, &vs2);
18389 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
18391 hr = IDirect3DDevice9_SetVertexShader(device, vs);
18392 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
18394 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_bad, &ps);
18395 ok(hr == D3DERR_INVALIDCALL, "CreatePixelShader returned hr %#x.\n", hr);
18397 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
18398 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
18399 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_2, &ps2);
18400 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
18402 hr = IDirect3DDevice9_SetPixelShader(device, ps);
18403 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18405 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
18406 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18407 hr = IDirect3DDevice9_BeginScene(device);
18408 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18409 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18410 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18411 hr = IDirect3DDevice9_EndScene(device);
18412 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18414 for (i = 0; i < sizeof(expected_colors) / sizeof(expected_colors[0]); ++i)
18416 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
18417 ok (color_match(color, expected_colors[i].expected_color, 1)
18418 || broken(color_match(color, expected_colors[i].broken_color, 1)),
18419 "Got unexpected color 0x%08x, case %u.\n", color, i);
18422 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
18423 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18425 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
18426 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18427 hr = IDirect3DDevice9_BeginScene(device);
18428 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18429 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18430 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18431 hr = IDirect3DDevice9_EndScene(device);
18432 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18434 for (i = 0; i < sizeof(expected_colors) / sizeof(expected_colors[0]); ++i)
18436 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
18437 ok (color_match(color, expected_colors[i].expected_color, 1)
18438 || broken(color_match(color, expected_colors[i].broken_color, 1)),
18439 "Got unexpected color 0x%08x, case %u.\n", color, i);
18442 hr = IDirect3DDevice9_SetVertexShader(device, vs2);
18443 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
18445 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
18446 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18447 hr = IDirect3DDevice9_BeginScene(device);
18448 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18449 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18450 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18451 hr = IDirect3DDevice9_EndScene(device);
18452 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18454 for (i = 0; i < sizeof(expected_colors) / sizeof(expected_colors[0]); ++i)
18456 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
18457 ok (color_match(color, expected_colors[i].expected_color, 1),
18458 "Got unexpected color 0x%08x, case %u.\n", color, i);
18461 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18462 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18464 IDirect3DPixelShader9_Release(ps2);
18465 IDirect3DPixelShader9_Release(ps);
18466 IDirect3DVertexShader9_Release(vs2);
18467 IDirect3DVertexShader9_Release(vs);
18468 IDirect3DVertexDeclaration9_Release(vertex_declaration);
18469 refcount = IDirect3DDevice9_Release(device);
18470 ok(!refcount, "Device has %u references left.\n", refcount);
18472 done:
18473 IDirect3D9_Release(d3d);
18474 DestroyWindow(window);
18477 static void test_table_fog_zw(void)
18479 HRESULT hr;
18480 IDirect3DDevice9 *device;
18481 IDirect3D9 *d3d;
18482 ULONG refcount;
18483 HWND window;
18484 D3DCOLOR color;
18485 D3DCAPS9 caps;
18486 static struct
18488 struct vec4 position;
18489 D3DCOLOR diffuse;
18491 quad[] =
18493 {{ 0.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
18494 {{640.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
18495 {{ 0.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
18496 {{640.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
18498 static const D3DMATRIX identity =
18500 1.0f, 0.0f, 0.0f, 0.0f,
18501 0.0f, 1.0f, 0.0f, 0.0f,
18502 0.0f, 0.0f, 1.0f, 0.0f,
18503 0.0f, 0.0f, 0.0f, 1.0f
18504 }}};
18505 static const struct
18507 float z, w;
18508 D3DZBUFFERTYPE z_test;
18509 D3DCOLOR color;
18511 tests[] =
18513 {0.7f, 0.0f, D3DZB_TRUE, 0x004cb200},
18514 {0.7f, 0.0f, D3DZB_FALSE, 0x004cb200},
18515 {0.7f, 0.3f, D3DZB_TRUE, 0x004cb200},
18516 {0.7f, 0.3f, D3DZB_FALSE, 0x004cb200},
18517 {0.7f, 3.0f, D3DZB_TRUE, 0x004cb200},
18518 {0.7f, 3.0f, D3DZB_FALSE, 0x004cb200},
18519 {0.3f, 0.0f, D3DZB_TRUE, 0x00b24c00},
18520 {0.3f, 0.0f, D3DZB_FALSE, 0x00b24c00},
18522 unsigned int i;
18524 window = create_window();
18525 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18526 ok(!!d3d, "Failed to create a D3D object.\n");
18528 if (!(device = create_device(d3d, window, window, TRUE)))
18530 skip("Failed to create a D3D device, skipping tests.\n");
18531 IDirect3D9_Release(d3d);
18532 DestroyWindow(window);
18533 return;
18536 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18537 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18538 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
18540 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping POSITIONT table fog test.\n");
18541 goto done;
18544 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18545 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18546 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
18547 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18548 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
18549 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18550 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
18551 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
18552 /* Work around an AMD Windows driver bug. Needs a proj matrix applied redundantly. */
18553 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
18554 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
18555 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
18556 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18557 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
18558 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
18560 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
18562 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
18563 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18565 quad[0].position.z = tests[i].z;
18566 quad[1].position.z = tests[i].z;
18567 quad[2].position.z = tests[i].z;
18568 quad[3].position.z = tests[i].z;
18569 quad[0].position.w = tests[i].w;
18570 quad[1].position.w = tests[i].w;
18571 quad[2].position.w = tests[i].w;
18572 quad[3].position.w = tests[i].w;
18573 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, tests[i].z_test);
18574 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18576 hr = IDirect3DDevice9_BeginScene(device);
18577 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18578 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
18579 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18580 hr = IDirect3DDevice9_EndScene(device);
18581 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18583 color = getPixelColor(device, 320, 240);
18584 ok(color_match(color, tests[i].color, 2),
18585 "Got unexpected color 0x%08x, expected 0x%08x, case %u.\n", color, tests[i].color, i);
18586 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18587 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18590 done:
18591 refcount = IDirect3DDevice9_Release(device);
18592 ok(!refcount, "Device has %u references left.\n", refcount);
18593 IDirect3D9_Release(d3d);
18594 DestroyWindow(window);
18597 static void test_signed_formats(void)
18599 IDirect3DDevice9 *device;
18600 HWND window;
18601 HRESULT hr;
18602 unsigned int i, j, x, y;
18603 IDirect3DTexture9 *texture, *texture_sysmem;
18604 IDirect3DSurface9 *src_surface, *dst_surface;
18605 D3DLOCKED_RECT locked_rect;
18606 IDirect3DPixelShader9 *shader, *shader_alpha;
18607 IDirect3D9 *d3d;
18608 D3DCOLOR color;
18609 D3DCAPS9 caps;
18610 ULONG refcount;
18612 /* The input data was designed for D3DFMT_L6V5U5 and then transferred
18613 * to the other formats because L6V5U5 is the lowest precision format.
18614 * It tests the extreme values -1.0 (-16) and 1.0 (15) for U/V and
18615 * 0.0 (0) and 1.0 (63) for L, the neutral point 0 as well as -1 and 1.
18616 * Some other intermediate values are tested too. The input value -15
18617 * (min + 1) is tested as well. Unlike what OpenGL 4.4 says in section
18618 * 2.3.4.1, this value does not represent -1.0. In the interest of re-
18619 * using the expected output data the 8 bit and 16 bit values in V8U8
18620 * and V16U16 match (post-normalization) the 5 bit input values. Thus
18621 * -1, 1 and -127 are not tested in V8U8.
18623 * 8 bit specific values like -127 are tested in the Q channel of
18624 * D3DFMT_Q8W8V8U8. Here d3d seems to follow the rules from the GL
18625 * spec. AMD's r200 is broken though and returns a value < -1.0 for
18626 * -128. The difference between using -127 or -128 as the lowest
18627 * possible value gets lost in the slop of 1 though. */
18628 static const USHORT content_v8u8[4][4] =
18630 {0x0000, 0x7f7f, 0x8880, 0x0000},
18631 {0x0080, 0x8000, 0x7f00, 0x007f},
18632 {0x193b, 0xe8c8, 0x0808, 0xf8f8},
18633 {0x4444, 0xc0c0, 0xa066, 0x22e0},
18635 static const DWORD content_v16u16[4][4] =
18637 {0x00000000, 0x7fff7fff, 0x88008000, 0x00000000},
18638 {0x00008000, 0x80000000, 0x7fff0000, 0x00007fff},
18639 {0x19993bbb, 0xe800c800, 0x08880888, 0xf800f800},
18640 {0x44444444, 0xc000c000, 0xa0006666, 0x2222e000},
18642 static const DWORD content_q8w8v8u8[4][4] =
18644 {0x00000000, 0xff7f7f7f, 0x7f008880, 0x817f0000},
18645 {0x10000080, 0x20008000, 0x30007f00, 0x4000007f},
18646 {0x5020193b, 0x6028e8c8, 0x70020808, 0x807ff8f8},
18647 {0x90414444, 0xa000c0c0, 0x8261a066, 0x834922e0},
18649 static const DWORD content_x8l8v8u8[4][4] =
18651 {0x00000000, 0x00ff7f7f, 0x00008880, 0x00ff0000},
18652 {0x00000080, 0x00008000, 0x00007f00, 0x0000007f},
18653 {0x0041193b, 0x0051e8c8, 0x00040808, 0x00fff8f8},
18654 {0x00824444, 0x0000c0c0, 0x00c2a066, 0x009222e0},
18656 /* D3DFMT_L6V5U5 has poor precision on some GPUs. On a GeForce 7 the highest V and U value (15)
18657 * results in the output color 0xfb, which is 4 steps away from the correct value 0xff. It is
18658 * not the ~0xf0 you'd get if you blindly left-shifted the 5 bit value to form an 8 bit value
18659 * though.
18661 * There may also be an off-by-one bug involved: The value -7 should result in the output 0x47,
18662 * but ends up as 0x4d. Likewise, -3 becomes 0x6e instead of 0x67. Those values are close to
18663 * the proper results of -6 and -2.
18665 * On Wine the emulation with unsigned R5G6B5 has poor precision, e.g. the signed 0 becomes 16,
18666 * and ((16 / 31) - 0.5) * 2.0 is 0.032 instead of 0.000. The final output result we read back
18667 * is 0x84 instead of 0x80. */
18668 static const USHORT content_l6v5u5[4][4] =
18670 {0x0000, 0xfdef, 0x0230, 0xfc00},
18671 {0x0010, 0x0200, 0x01e0, 0x000f},
18672 {0x4067, 0x53b9, 0x0421, 0xffff},
18673 {0x8108, 0x0318, 0xc28c, 0x909c},
18675 static const struct
18677 D3DFORMAT format;
18678 const char *name;
18679 const void *content;
18680 SIZE_T pixel_size;
18681 BOOL blue, alpha;
18682 unsigned int slop, slop_broken, alpha_broken;
18684 formats[] =
18686 {D3DFMT_V8U8, "D3DFMT_V8U8", content_v8u8, sizeof(WORD), FALSE, FALSE, 1, 0, FALSE},
18687 {D3DFMT_V16U16, "D3DFMT_V16U16", content_v16u16, sizeof(DWORD), FALSE, FALSE, 1, 0, FALSE},
18688 {D3DFMT_Q8W8V8U8, "D3DFMT_Q8W8V8U8", content_q8w8v8u8, sizeof(DWORD), TRUE, TRUE, 1, 0, TRUE },
18689 {D3DFMT_X8L8V8U8, "D3DFMT_X8L8V8U8", content_x8l8v8u8, sizeof(DWORD), TRUE, FALSE, 1, 0, FALSE},
18690 {D3DFMT_L6V5U5, "D3DFMT_L6V5U5", content_l6v5u5, sizeof(WORD), TRUE, FALSE, 4, 7, FALSE},
18692 static const struct
18694 D3DPOOL pool;
18695 UINT width;
18696 RECT src_rect;
18697 POINT dst_point;
18699 tests[] =
18701 {D3DPOOL_SYSTEMMEM, 4, {1, 1, 2, 3}, {2, 0}},
18702 {D3DPOOL_SYSTEMMEM, 1, {0, 1, 1, 3}, {0, 0}},
18703 {D3DPOOL_MANAGED, 4, {1, 1, 2, 3}, {2, 0}},
18704 {D3DPOOL_MANAGED, 1, {0, 1, 1, 3}, {0, 0}},
18706 static const DWORD shader_code[] =
18708 0xffff0101, /* ps_1_1 */
18709 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0,5, 0,5 */
18710 0x00000042, 0xb00f0000, /* tex t0 */
18711 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
18712 0x0000ffff /* end */
18714 static const DWORD shader_code_alpha[] =
18716 /* The idea of this shader is to replicate the alpha value in .rg, and set
18717 * blue to 1.0 iff the alpha value is < -1.0 and 0.0 otherwise. */
18718 0xffff0101, /* ps_1_1 */
18719 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
18720 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
18721 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
18722 0x00000042, 0xb00f0000, /* tex t0 */
18723 0x00000004, 0x80070000, 0xb0ff0000, 0xa0e40000, 0xa0e40000, /* mad r0.rgb, t0.a, c0, c0 */
18724 0x00000003, 0x80080000, 0xb1ff0000, 0xa0e40000, /* sub r0.a, -t0.a, c0 */
18725 0x00000050, 0x80080000, 0x80ff0000, 0xa0ff0001, 0xa0ff0002, /* cnd r0.a, r0.a, c1.a, c2.a */
18726 0x00000005, 0x80070001, 0xa0e40001, 0x80e40000, /* mul r1.rgb, c1, r0 */
18727 0x00000004, 0x80070000, 0x80ff0000, 0xa0e40002, 0x80e40001, /* mad r0.rgb, r0.a, c2, r1 */
18728 0x0000ffff /* end */
18730 static const struct
18732 struct vec3 position;
18733 struct vec2 texcrd;
18735 quad[] =
18737 /* Flip the y coordinate to make the input and
18738 * output arrays easier to compare. */
18739 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 1.0f}},
18740 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 0.0f}},
18741 {{ 1.0f, -1.0f, 0.0f}, { 1.0f, 1.0f}},
18742 {{ 1.0f, 1.0f, 0.0f}, { 1.0f, 0.0f}},
18744 static const D3DCOLOR expected_alpha[4][4] =
18746 {0x00808000, 0x007f7f00, 0x00ffff00, 0x00000000},
18747 {0x00909000, 0x00a0a000, 0x00b0b000, 0x00c0c000},
18748 {0x00d0d000, 0x00e0e000, 0x00f0f000, 0x00000000},
18749 {0x00101000, 0x00202000, 0x00010100, 0x00020200},
18751 static const BOOL alpha_broken[4][4] =
18753 {FALSE, FALSE, FALSE, FALSE},
18754 {FALSE, FALSE, FALSE, FALSE},
18755 {FALSE, FALSE, FALSE, TRUE },
18756 {FALSE, FALSE, FALSE, FALSE},
18758 static const D3DCOLOR expected_colors[4][4] =
18760 {0x00808080, 0x00fefeff, 0x00010780, 0x008080ff},
18761 {0x00018080, 0x00800180, 0x0080fe80, 0x00fe8080},
18762 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
18763 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
18765 static const D3DCOLOR expected_colors2[4][4] =
18767 {0x00808080, 0x00fefeff, 0x00800180, 0x008080ff},
18768 {0x00018080, 0x00800180, 0x004767a8, 0x00fe8080},
18769 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
18770 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
18772 static const D3DCOLOR expected_colors3[4] =
18774 0x00018080,
18775 0x00ba98a0,
18776 0x00ba98a0,
18777 0x00c3c3c0,
18779 D3DCOLOR expected_color;
18781 window = create_window();
18782 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18783 ok(!!d3d, "Failed to create a D3D object.\n");
18785 if (!(device = create_device(d3d, window, window, TRUE)))
18787 skip("Failed to create a D3D device, skipping tests.\n");
18788 IDirect3D9_Release(d3d);
18789 DestroyWindow(window);
18790 return;
18793 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18794 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18796 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
18798 skip("Pixel shaders not supported, skipping converted format test.\n");
18799 goto done;
18802 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
18803 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18804 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
18805 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
18806 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
18807 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
18808 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_alpha, &shader_alpha);
18809 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
18811 for (i = 0; i < sizeof(formats) / sizeof(*formats); i++)
18813 hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
18814 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, formats[i].format);
18815 if (FAILED(hr))
18817 skip("Format %s not supported, skipping.\n", formats[i].name);
18818 continue;
18821 for (j = 0; j < sizeof(tests) / sizeof(*tests); j++)
18823 texture_sysmem = NULL;
18824 hr = IDirect3DDevice9_CreateTexture(device, tests[j].width, 4, 1, 0,
18825 formats[i].format, tests[j].pool, &texture, NULL);
18826 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
18828 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
18829 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
18830 for (y = 0; y < 4; y++)
18832 memcpy((char *)locked_rect.pBits + y * locked_rect.Pitch,
18833 (char *)formats[i].content + y * 4 * formats[i].pixel_size,
18834 tests[j].width * formats[i].pixel_size);
18836 hr = IDirect3DTexture9_UnlockRect(texture, 0);
18837 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
18839 if (tests[j].pool == D3DPOOL_SYSTEMMEM)
18841 texture_sysmem = texture;
18842 hr = IDirect3DDevice9_CreateTexture(device, tests[j].width, 4, 1, 0,
18843 formats[i].format, D3DPOOL_DEFAULT, &texture, NULL);
18844 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
18846 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture_sysmem,
18847 (IDirect3DBaseTexture9 *)texture);
18848 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
18851 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
18852 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
18853 hr = IDirect3DDevice9_SetPixelShader(device, shader_alpha);
18854 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18856 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
18857 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18858 hr = IDirect3DDevice9_BeginScene(device);
18859 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18860 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
18861 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18862 hr = IDirect3DDevice9_EndScene(device);
18863 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18865 for (y = 0; y < 4; y++)
18867 for (x = 0; x < tests[j].width; x++)
18869 BOOL r200_broken = formats[i].alpha_broken && alpha_broken[y][x];
18870 if (formats[i].alpha)
18871 expected_color = expected_alpha[y][x];
18872 else
18873 expected_color = 0x00ffff00;
18875 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
18876 ok(color_match(color, expected_color, 1) || broken(r200_broken),
18877 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
18878 expected_color, color, formats[i].name, x, y);
18881 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18882 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18884 hr = IDirect3DDevice9_SetPixelShader(device, shader);
18885 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18887 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
18888 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18889 hr = IDirect3DDevice9_BeginScene(device);
18890 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18891 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
18892 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18893 hr = IDirect3DDevice9_EndScene(device);
18894 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18896 for (y = 0; y < 4; y++)
18898 for (x = 0; x < tests[j].width; x++)
18900 expected_color = expected_colors[y][x];
18901 if (!formats[i].blue)
18902 expected_color |= 0x000000ff;
18904 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
18905 ok(color_match(color, expected_color, formats[i].slop)
18906 || broken(color_match(color, expected_color, formats[i].slop_broken)),
18907 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
18908 expected_color, color, formats[i].name, x, y);
18911 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18912 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18914 if (tests[j].pool != D3DPOOL_SYSTEMMEM)
18916 IDirect3DTexture9_Release(texture);
18917 continue;
18920 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &dst_surface);
18921 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x.\n", hr);
18922 IDirect3DTexture9_GetSurfaceLevel(texture_sysmem, 0, &src_surface);
18923 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x.\n", hr);
18925 hr = IDirect3DDevice9_UpdateSurface(device, src_surface,
18926 &tests[j].src_rect, dst_surface, &tests[j].dst_point);
18927 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
18929 IDirect3DSurface9_Release(dst_surface);
18930 IDirect3DSurface9_Release(src_surface);
18932 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00003300, 0.0f, 0);
18933 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18934 hr = IDirect3DDevice9_BeginScene(device);
18935 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18936 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
18937 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18938 hr = IDirect3DDevice9_EndScene(device);
18939 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18941 for (y = 0; y < 4; y++)
18943 for (x = 0; x < tests[j].width; x++)
18945 if (tests[j].width == 4)
18946 expected_color = expected_colors2[y][x];
18947 else
18948 expected_color = expected_colors3[y];
18950 if (!formats[i].blue)
18951 expected_color |= 0x000000ff;
18953 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
18954 ok(color_match(color, expected_color, formats[i].slop)
18955 || broken(color_match(color, expected_color, formats[i].slop_broken)),
18956 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
18957 expected_color, color, formats[i].name, x, y);
18960 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18961 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18963 IDirect3DTexture9_Release(texture_sysmem);
18964 IDirect3DTexture9_Release(texture);
18968 IDirect3DPixelShader9_Release(shader);
18969 IDirect3DPixelShader9_Release(shader_alpha);
18971 done:
18972 refcount = IDirect3DDevice9_Release(device);
18973 ok(!refcount, "Device has %u references left.\n", refcount);
18974 IDirect3D9_Release(d3d);
18975 DestroyWindow(window);
18978 static void test_multisample_mismatch(void)
18980 IDirect3DDevice9 *device;
18981 IDirect3D9 *d3d;
18982 HWND window;
18983 HRESULT hr;
18984 D3DCOLOR color;
18985 ULONG refcount;
18986 IDirect3DSurface9 *rt, *rt_multi, *ds;
18987 static const struct
18989 struct vec3 position;
18990 DWORD color;
18992 quad[] =
18994 {{ -1.0f, -1.0f, 0.0f}, 0x000000ff},
18995 {{ -1.0f, 1.0f, 0.0f}, 0x000000ff},
18996 {{ 1.0f, -1.0f, 1.0f}, 0x000000ff},
18997 {{ 1.0f, 1.0f, 1.0f}, 0x000000ff},
19000 window = create_window();
19001 d3d = Direct3DCreate9(D3D_SDK_VERSION);
19002 ok(!!d3d, "Failed to create a D3D object.\n");
19003 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
19004 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
19006 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample mismatch test.\n");
19007 IDirect3D9_Release(d3d);
19008 return;
19010 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
19011 D3DFMT_D24X8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
19013 skip("Multisampling not supported for D3DFMT_D24X8, skipping multisample mismatch test.\n");
19014 IDirect3D9_Release(d3d);
19015 return;
19018 if (!(device = create_device(d3d, window, window, TRUE)))
19020 skip("Failed to create a D3D device, skipping tests.\n");
19021 IDirect3D9_Release(d3d);
19022 DestroyWindow(window);
19023 return;
19026 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
19027 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt_multi, NULL);
19028 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
19030 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.1f, 0);
19031 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19033 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
19034 ok(SUCCEEDED(hr), "Failed to set depth stencil, hr %#x.\n", hr);
19035 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
19036 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
19037 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
19038 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19040 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
19041 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19042 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
19043 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19045 /* Clear with incompatible buffers. Partial and combined clears. */
19046 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
19047 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19048 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.3f, 0);
19049 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19050 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 0.5f, 0);
19051 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19053 /* The color buffer is reliably cleared on AMD and Nvidia GPUs. */
19054 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
19055 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19056 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
19057 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
19058 color = getPixelColor(device, 320, 240);
19059 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
19060 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19061 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19063 /* Check depth buffer values. AMD GPUs (r500 and evergreen tested) clear the depth buffer
19064 * like you'd expect in a correct framebuffer setup. Nvidia doesn't clear it, neither in
19065 * the Z only clear case nor in the combined clear case. */
19066 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
19067 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
19068 hr = IDirect3DDevice9_BeginScene(device);
19069 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19070 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19071 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19072 hr = IDirect3DDevice9_EndScene(device);
19073 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19074 color = getPixelColor(device, 62, 240);
19075 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
19076 color = getPixelColor(device, 64, 240);
19077 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x000000ff, 1)),
19078 "Got unexpected color 0x%08x.\n", color);
19079 color = getPixelColor(device, 318, 240);
19080 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x000000ff, 1)),
19081 "Got unexpected color 0x%08x.\n", color);
19082 color = getPixelColor(device, 322, 240);
19083 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
19084 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19085 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19087 /* Draw with incompatible buffers. AMD even performs Z testing, and the Z test
19088 * results appear to be correct for this simple draw. Nvidia doesn't draw unless
19089 * the depth test is disabled. Setting ZFUNC = ALWAYS doesn't make the geometry
19090 * show up either. Only test the ZENABLE = FALSE case for now. */
19091 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
19092 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19093 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
19094 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19095 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
19096 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19097 hr = IDirect3DDevice9_BeginScene(device);
19098 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19099 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19100 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19101 hr = IDirect3DDevice9_EndScene(device);
19102 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19104 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
19105 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19106 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
19107 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
19108 color = getPixelColor(device, 320, 240);
19109 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
19110 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19111 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19113 IDirect3DSurface9_Release(ds);
19115 /* Test the reverse situation: Multisampled depth buffer, single sampled color buffer.
19116 * Color clears work as expected, AMD also clears the depth buffer, Nvidia does not. */
19117 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24X8,
19118 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
19119 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#x.\n", hr);
19120 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
19121 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
19122 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
19123 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19124 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ffff00, 0.1f, 0);
19125 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19127 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
19128 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19129 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
19130 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19131 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.3f, 0);
19132 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19133 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 0.5f, 0);
19134 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19136 color = getPixelColor(device, 320, 240);
19137 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
19138 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19139 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19141 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
19142 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19143 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
19144 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19145 hr = IDirect3DDevice9_BeginScene(device);
19146 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19147 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19148 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19149 hr = IDirect3DDevice9_EndScene(device);
19150 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19152 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
19153 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19154 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
19155 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
19156 color = getPixelColor(device, 62, 240);
19157 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
19158 color = getPixelColor(device, 318, 240);
19159 ok(color_match(color, 0x00ffff00, 1) || broken(color_match(color, 0x000000ff, 1)),
19160 "Got unexpected color 0x%08x.\n", color);
19161 color = getPixelColor(device, 322, 240);
19162 ok(color_match(color, 0x00ffff00, 1), "Got unexpected color 0x%08x.\n", color);
19163 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19164 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19166 /* Draw with a single sampled color buffer and a multisampled depth buffer. Again
19167 * AMD seems to perform correct Z testing, Nvidia doesn't draw unless the Z test
19168 * is disabled. Again only test the ZENABLE = FALSE case. */
19169 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
19170 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19171 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
19172 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19173 hr = IDirect3DDevice9_BeginScene(device);
19174 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19175 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19176 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19177 hr = IDirect3DDevice9_EndScene(device);
19178 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19179 color = getPixelColor(device, 320, 240);
19180 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
19181 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19182 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19184 IDirect3DSurface9_Release(rt);
19185 IDirect3DSurface9_Release(ds);
19186 IDirect3DSurface9_Release(rt_multi);
19188 refcount = IDirect3DDevice9_Release(device);
19189 ok(!refcount, "Device has %u references left.\n", refcount);
19190 IDirect3D9_Release(d3d);
19191 DestroyWindow(window);
19194 static void test_texcoordindex(void)
19196 static const D3DMATRIX mat =
19198 1.0f, 0.0f, 0.0f, 0.0f,
19199 0.0f, 0.0f, 0.0f, 0.0f,
19200 0.0f, 0.0f, 0.0f, 0.0f,
19201 0.0f, 0.0f, 0.0f, 0.0f,
19202 }}};
19203 static const struct
19205 struct vec3 pos;
19206 struct vec2 texcoord1;
19207 struct vec2 texcoord2;
19208 struct vec2 texcoord3;
19210 quad[] =
19212 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 1.0f}},
19213 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 0.0f}},
19214 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}, {1.0f, 0.0f}, {0.0f, 1.0f}},
19215 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 0.0f}},
19217 IDirect3DDevice9 *device;
19218 IDirect3D9 *d3d9;
19219 HWND window;
19220 HRESULT hr;
19221 IDirect3DTexture9 *texture1, *texture2;
19222 D3DLOCKED_RECT locked_rect;
19223 ULONG refcount;
19224 D3DCOLOR color;
19225 DWORD *ptr;
19227 window = create_window();
19228 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
19229 ok(!!d3d9, "Failed to create a D3D object.\n");
19230 if (!(device = create_device(d3d9, window, window, TRUE)))
19232 skip("Failed to create a D3D device, skipping tests.\n");
19233 IDirect3D9_Release(d3d9);
19234 DestroyWindow(window);
19235 return;
19238 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture1, NULL);
19239 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
19240 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
19241 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
19243 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
19244 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
19245 ptr = locked_rect.pBits;
19246 ptr[0] = 0xff000000;
19247 ptr[1] = 0xff00ff00;
19248 ptr[2] = 0xff0000ff;
19249 ptr[3] = 0xff00ffff;
19250 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
19251 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
19253 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
19254 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
19255 ptr = locked_rect.pBits;
19256 ptr[0] = 0xff000000;
19257 ptr[1] = 0xff0000ff;
19258 ptr[2] = 0xffff0000;
19259 ptr[3] = 0xffff00ff;
19260 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
19261 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
19263 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture1);
19264 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
19265 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *)texture2);
19266 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
19267 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX3);
19268 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
19269 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
19270 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
19271 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
19272 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
19273 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
19274 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
19275 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
19276 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
19277 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
19278 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
19279 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
19280 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
19281 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
19282 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
19284 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXCOORDINDEX, 1);
19285 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
19286 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 0);
19287 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
19289 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
19290 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19292 hr = IDirect3DDevice9_BeginScene(device);
19293 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19294 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19295 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19296 hr = IDirect3DDevice9_EndScene(device);
19297 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19299 color = getPixelColor(device, 160, 120);
19300 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
19301 color = getPixelColor(device, 480, 120);
19302 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19303 color = getPixelColor(device, 160, 360);
19304 ok(color_match(color, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color);
19305 color = getPixelColor(device, 480, 360);
19306 ok(color_match(color, 0x00ffffff, 2), "Got unexpected color 0x%08x.\n", color);
19308 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
19309 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
19310 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE1, &mat);
19311 ok(SUCCEEDED(hr), "Failed to set transformation matrix, hr %#x.\n", hr);
19313 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
19314 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19316 hr = IDirect3DDevice9_BeginScene(device);
19317 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19318 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19319 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19320 hr = IDirect3DDevice9_EndScene(device);
19321 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19323 color = getPixelColor(device, 160, 120);
19324 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
19325 color = getPixelColor(device, 480, 120);
19326 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19327 color = getPixelColor(device, 160, 360);
19328 ok(color_match(color, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color);
19329 color = getPixelColor(device, 480, 360);
19330 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19332 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
19333 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
19334 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 2);
19335 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
19337 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
19338 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19340 hr = IDirect3DDevice9_BeginScene(device);
19341 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19342 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19343 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19344 hr = IDirect3DDevice9_EndScene(device);
19345 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19347 color = getPixelColor(device, 160, 120);
19348 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
19349 color = getPixelColor(device, 480, 120);
19350 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19351 color = getPixelColor(device, 160, 360);
19352 ok(color_match(color, 0x00ff00ff, 2), "Got unexpected color 0x%08x.\n", color);
19353 color = getPixelColor(device, 480, 360);
19354 ok(color_match(color, 0x00ffff00, 2), "Got unexpected color 0x%08x.\n", color);
19356 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19357 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19359 IDirect3DTexture9_Release(texture1);
19360 IDirect3DTexture9_Release(texture2);
19362 refcount = IDirect3DDevice9_Release(device);
19363 ok(!refcount, "Device has %u references left.\n", refcount);
19364 IDirect3D9_Release(d3d9);
19365 DestroyWindow(window);
19368 static void test_vertex_blending(void)
19370 IDirect3DVertexDeclaration9 *vertex_declaration;
19371 IDirect3DDevice9 *device;
19372 IDirect3D9 *d3d;
19373 D3DCAPS9 caps;
19374 D3DCOLOR color;
19375 ULONG refcount;
19376 HWND window;
19377 HRESULT hr;
19378 int i;
19380 static const D3DMATRIX view_mat =
19382 2.0f / 10.0f, 0.0f, 0.0f, 0.0f,
19383 0.0f, 2.0f / 10.0f, 0.0f, 0.0f,
19384 0.0f, 0.0f, 1.0f, 0.0f,
19385 0.0f, 0.0f, 0.0f, 1.0f
19386 }}},
19387 upper_left =
19389 1.0f, 0.0f, 0.0f, 0.0f,
19390 0.0f, 1.0f, 0.0f, 0.0f,
19391 0.0f, 0.0f, 1.0f, 0.0f,
19392 -4.0f, 4.0f, 0.0f, 1.0f
19393 }}},
19394 lower_left =
19396 1.0f, 0.0f, 0.0f, 0.0f,
19397 0.0f, 1.0f, 0.0f, 0.0f,
19398 0.0f, 0.0f, 1.0f, 0.0f,
19399 -4.0f, -4.0f, 0.0f, 1.0f
19400 }}},
19401 upper_right =
19403 1.0f, 0.0f, 0.0f, 0.0f,
19404 0.0f, 1.0f, 0.0f, 0.0f,
19405 0.0f, 0.0f, 1.0f, 0.0f,
19406 4.0f, 4.0f, 0.0f, 1.0f
19407 }}},
19408 lower_right =
19410 1.0f, 0.0f, 0.0f, 0.0f,
19411 0.0f, 1.0f, 0.0f, 0.0f,
19412 0.0f, 0.0f, 1.0f, 0.0f,
19413 4.0f, -4.0f, 0.0f, 1.0f
19414 }}};
19416 static const POINT quad_upper_right_points[] =
19418 {576, 48}, {-1, -1},
19420 quad_upper_right_empty_points[] =
19422 {64, 48}, {64, 432}, {576, 432}, {320, 240}, {-1, -1}
19424 quad_center_points[] =
19426 {320, 240}, {-1, -1}
19428 quad_center_empty_points[] =
19430 {64, 48}, {576, 48}, {64, 432}, {576, 432}, {-1, -1}
19432 quad_upper_center_points[] =
19434 {320, 48}, {-1, -1}
19436 quad_upper_center_empty_points[] =
19438 {320, 240}, {64, 48}, {576, 48}, {-1, -1}
19440 quad_fullscreen_points[] =
19442 {320, 48}, {320, 240}, {64, 48}, {576, 48}, {64, 432}, {576, 432}, {-1, -1}
19444 quad_fullscreen_empty_points[] =
19446 {-1, -1}
19449 static const struct
19451 DWORD fvf;
19452 D3DVERTEXELEMENT9 decl_elements[3];
19453 struct
19455 struct
19457 struct vec3 position;
19458 struct vec3 blendweights;
19460 vertex_data_float[4];
19461 struct
19463 struct vec3 position;
19464 D3DCOLOR blendweights;
19466 vertex_data_d3dcolor[4];
19467 } s;
19468 const POINT *quad_points;
19469 const POINT *empty_points;
19471 tests[] =
19473 /* upper right */
19475 D3DFVF_XYZB3,
19476 {{0}},
19477 {{{{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
19478 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
19479 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
19480 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}}}},
19481 quad_upper_right_points, quad_upper_right_empty_points
19483 /* center */
19485 D3DFVF_XYZB3,
19486 {{0}},
19487 {{{{-1.0f, -1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}},
19488 {{-1.0f, 1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}},
19489 {{ 1.0f, -1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}},
19490 {{ 1.0f, 1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}}}},
19491 quad_center_points, quad_center_empty_points
19493 /* upper center */
19495 D3DFVF_XYZB3,
19496 {{0}},
19497 {{{{-1.0f, -1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}},
19498 {{-1.0f, 1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}},
19499 {{ 1.0f, -1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}},
19500 {{ 1.0f, 1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}}}},
19501 quad_upper_center_points, quad_upper_center_empty_points
19503 /* full screen */
19505 D3DFVF_XYZB3,
19506 {{0}},
19507 {{{{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}},
19508 {{-1.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}},
19509 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}},
19510 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}}}},
19511 quad_fullscreen_points, quad_fullscreen_empty_points
19513 /* D3DCOLOR, full screen */
19517 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
19518 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
19519 D3DDECL_END()
19521 {{{{0}}},
19522 {{{-1.0f, -1.0f, 0.0f}, 0x0000ff00},
19523 {{-1.0f, 1.0f, 0.0f}, 0x00ff0000},
19524 {{ 1.0f, -1.0f, 0.0f}, 0x000000ff},
19525 {{ 1.0f, 1.0f, 0.0f}, 0x00000000}}},
19526 quad_fullscreen_points, quad_fullscreen_empty_points
19530 window = create_window();
19531 d3d = Direct3DCreate9(D3D_SDK_VERSION);
19532 ok(!!d3d, "Failed to create a D3D object.\n");
19533 if (!(device = create_device(d3d, window, window, TRUE)))
19535 skip("Failed to create a D3D device, skipping tests.\n");
19536 goto done;
19539 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
19540 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
19541 if (caps.MaxVertexBlendMatrices < 4)
19543 skip("Only %u vertex blend matrices supported, skipping tests.\n", caps.MaxVertexBlendMatrices);
19544 IDirect3DDevice9_Release(device);
19545 goto done;
19548 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
19549 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
19551 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &view_mat);
19552 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19554 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &upper_left);
19555 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19556 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(1), &lower_left);
19557 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19558 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(2), &lower_right);
19559 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19560 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(3), &upper_right);
19561 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19563 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_VERTEXBLEND, D3DVBF_3WEIGHTS);
19564 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed %08x\n", hr);
19566 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
19568 const POINT *point;
19570 if (tests[i].fvf)
19572 hr = IDirect3DDevice9_SetFVF(device, tests[i].fvf);
19573 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
19574 vertex_declaration = NULL;
19576 else
19578 hr = IDirect3DDevice9_CreateVertexDeclaration(device, tests[i].decl_elements, &vertex_declaration);
19579 ok(SUCCEEDED(hr), "Failed to create vertex declaration, hr %#x.\n", hr);
19580 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
19581 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
19584 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
19585 ok(SUCCEEDED(hr), "Failed to clear %08x\n", hr);
19587 hr = IDirect3DDevice9_BeginScene(device);
19588 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19590 if (tests[i].fvf)
19591 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
19592 tests[i].s.vertex_data_float, sizeof(*tests[i].s.vertex_data_float));
19593 else
19594 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
19595 tests[i].s.vertex_data_d3dcolor, sizeof(*tests[i].s.vertex_data_d3dcolor));
19596 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19598 hr = IDirect3DDevice9_EndScene(device);
19599 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19601 point = tests[i].quad_points;
19602 while (point->x != -1 && point->y != -1)
19604 color = getPixelColor(device, point->x, point->y);
19605 ok(color_match(color, 0x00ffffff, 1), "Expected quad at %dx%d.\n", point->x, point->y);
19606 ++point;
19609 point = tests[i].empty_points;
19610 while (point->x != -1 && point->y != -1)
19612 color = getPixelColor(device, point->x, point->y);
19613 ok(color_match(color, 0x00000000, 1), "Unexpected quad at %dx%d.\n", point->x, point->y);
19614 ++point;
19617 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19618 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19620 if (vertex_declaration)
19621 IDirect3DVertexDeclaration9_Release(vertex_declaration);
19624 refcount = IDirect3DDevice9_Release(device);
19625 ok(!refcount, "Device has %u references left.\n", refcount);
19627 done:
19628 IDirect3D9_Release(d3d);
19629 DestroyWindow(window);
19632 static void test_updatetexture(void)
19634 BOOL r32f_supported, ati2n_supported, do_visual_test;
19635 IDirect3DBaseTexture9 *src, *dst;
19636 unsigned int t, i, f, l, x, y, z;
19637 D3DLOCKED_RECT locked_rect;
19638 D3DLOCKED_BOX locked_box;
19639 IDirect3DDevice9 *device;
19640 IDirect3D9 *d3d9;
19641 ULONG refcount;
19642 D3DCOLOR color;
19643 D3DCAPS9 caps;
19644 HWND window;
19645 HRESULT hr;
19646 static const struct
19648 struct vec3 pos;
19649 struct vec2 texcoord;
19651 quad[] =
19653 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}},
19654 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}},
19655 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}},
19656 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
19658 static const struct
19660 struct vec3 pos;
19661 struct vec3 texcoord;
19663 quad_cube_tex[] =
19665 {{-1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, 0.5f}},
19666 {{-1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, 0.5f}},
19667 {{ 1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, -0.5f}},
19668 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, -0.5f}},
19670 static const struct
19672 UINT src_width, src_height;
19673 UINT dst_width, dst_height;
19674 UINT src_levels, dst_levels;
19675 D3DFORMAT src_format, dst_format;
19676 BOOL broken;
19678 tests[] =
19680 {8, 8, 8, 8, 0, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 0 */
19681 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 1 */
19682 {8, 8, 8, 8, 2, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 2 */
19683 {8, 8, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 3 */
19684 {8, 8, 8, 8, 4, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 4 */
19685 {8, 8, 2, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 5 */
19686 /* The WARP renderer doesn't handle these cases correctly. */
19687 {8, 8, 8, 8, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 6 */
19688 {8, 8, 4, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 7 */
19689 /* Not clear what happens here on Windows, it doesn't make much sense
19690 * though (on Nvidia it seems to upload the 4x4 surface into the 7x7
19691 * one or something like that). */
19692 /* {8, 8, 7, 7, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
19693 {8, 8, 8, 8, 1, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 8 */
19694 {4, 4, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 9 */
19695 /* This one causes weird behavior on Windows (it probably writes out
19696 * of the texture memory). */
19697 /* {8, 8, 4, 4, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
19698 {8, 4, 4, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 10 */
19699 {8, 4, 2, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 11 */
19700 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8, FALSE}, /* 12 */
19701 {8, 8, 8, 8, 4, 4, D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 13 */
19702 /* The data is converted correctly on AMD, on Nvidia nothing happens
19703 * (it draws a black quad). */
19704 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_R5G6B5, TRUE}, /* 14 */
19705 /* Here the data is converted on AMD, just copied and "reinterpreted" as
19706 * a 32 bit float on Nvidia (specifically the tested value becomes a
19707 * very small float number which we get as 0 in the test). */
19708 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_R32F, TRUE}, /* 15 */
19709 /* This one doesn't seem to give the expected results on AMD. */
19710 /* {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_Q8W8V8U8, FALSE}, */
19711 {8, 8, 8, 8, 4, 4, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 16 */
19712 {8, 8, 8, 8, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 17 */
19713 {8, 8, 2, 2, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 18 */
19715 static const struct
19717 D3DRESOURCETYPE type;
19718 DWORD fvf;
19719 const void *quad;
19720 unsigned int vertex_size;
19721 DWORD cap;
19722 const char *name;
19724 texture_types[] =
19726 {D3DRTYPE_TEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
19727 quad, sizeof(*quad), D3DPTEXTURECAPS_MIPMAP, "2D mipmapped"},
19729 {D3DRTYPE_CUBETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0),
19730 quad_cube_tex, sizeof(*quad_cube_tex), D3DPTEXTURECAPS_CUBEMAP, "Cube"},
19732 {D3DRTYPE_VOLUMETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
19733 quad, sizeof(*quad), D3DPTEXTURECAPS_VOLUMEMAP, "Volume"}
19736 window = create_window();
19737 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
19738 ok(!!d3d9, "Failed to create a D3D object.\n");
19739 if (!(device = create_device(d3d9, window, window, TRUE)))
19741 skip("Failed to create a D3D device, skipping tests.\n");
19742 IDirect3D9_Release(d3d9);
19743 DestroyWindow(window);
19744 return;
19747 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
19748 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
19750 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
19751 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#x.\n", hr);
19752 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
19753 ok(SUCCEEDED(hr), "Failed to set texture clamping state, hr %#x.\n", hr);
19754 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
19755 ok(SUCCEEDED(hr), "Failed to set texture clamping state, hr %#x.\n", hr);
19756 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
19757 ok(SUCCEEDED(hr), "Failed to set texture clamping state, hr %#x.\n", hr);
19758 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
19759 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19760 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
19761 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#x.\n", hr);
19762 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
19763 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#x.\n", hr);
19765 for (t = 0; t < sizeof(texture_types) / sizeof(*texture_types); ++t)
19767 if (!(caps.TextureCaps & texture_types[t].cap))
19769 skip("%s textures not supported, skipping some tests.\n", texture_types[t].name);
19770 continue;
19772 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
19773 D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_FILTER, texture_types[t].type, D3DFMT_A8R8G8B8)))
19775 skip("%s D3DFMT_A8R8G8B8 texture filtering is not supported, skipping some tests.\n",
19776 texture_types[t].name);
19777 continue;
19779 r32f_supported = TRUE;
19780 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
19781 D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_FILTER, texture_types[t].type, D3DFMT_R32F)))
19783 skip("%s R32F textures are not supported, skipping some tests.\n", texture_types[t].name);
19784 r32f_supported = FALSE;
19786 ati2n_supported = TRUE;
19787 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
19788 D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_FILTER, texture_types[t].type, MAKEFOURCC('A','T','I','2'))))
19790 skip("%s ATI2N textures are not supported, skipping some tests.\n", texture_types[t].name);
19791 ati2n_supported = FALSE;
19794 hr = IDirect3DDevice9_SetFVF(device, texture_types[t].fvf);
19795 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
19797 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
19799 if (tests[i].dst_format == D3DFMT_R32F && !r32f_supported)
19800 continue;
19801 if (tests[i].dst_format == MAKEFOURCC('A','T','I','2') && !ati2n_supported)
19802 continue;
19804 switch (texture_types[t].type)
19806 case D3DRTYPE_TEXTURE:
19807 hr = IDirect3DDevice9_CreateTexture(device,
19808 tests[i].src_width, tests[i].src_height,
19809 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
19810 (IDirect3DTexture9 **)&src, NULL);
19811 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19812 hr = IDirect3DDevice9_CreateTexture(device,
19813 tests[i].dst_width, tests[i].dst_height,
19814 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
19815 (IDirect3DTexture9 **)&dst, NULL);
19816 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19817 break;
19818 case D3DRTYPE_CUBETEXTURE:
19819 hr = IDirect3DDevice9_CreateCubeTexture(device,
19820 tests[i].src_width,
19821 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
19822 (IDirect3DCubeTexture9 **)&src, NULL);
19823 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19824 hr = IDirect3DDevice9_CreateCubeTexture(device,
19825 tests[i].dst_width,
19826 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
19827 (IDirect3DCubeTexture9 **)&dst, NULL);
19828 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19829 break;
19830 case D3DRTYPE_VOLUMETEXTURE:
19831 hr = IDirect3DDevice9_CreateVolumeTexture(device,
19832 tests[i].src_width, tests[i].src_height, tests[i].src_width,
19833 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
19834 (IDirect3DVolumeTexture9 **)&src, NULL);
19835 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19836 hr = IDirect3DDevice9_CreateVolumeTexture(device,
19837 tests[i].dst_width, tests[i].dst_height, tests[i].dst_width,
19838 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
19839 (IDirect3DVolumeTexture9 **)&dst, NULL);
19840 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19841 break;
19842 default:
19843 trace("Unexpected resource type.\n");
19846 /* Skip the visual part of the test for ATI2N (laziness) and cases that
19847 * give a different (and unlikely to be useful) result. */
19848 do_visual_test = (tests[i].src_format == D3DFMT_A8R8G8B8 || tests[i].src_format == D3DFMT_X8R8G8B8)
19849 && tests[i].src_levels != 0
19850 && tests[i].src_width >= tests[i].dst_width && tests[i].src_height >= tests[i].dst_height
19851 && !(tests[i].src_width > tests[i].src_height && tests[i].dst_width < tests[i].dst_height);
19853 if (do_visual_test)
19855 DWORD *ptr = NULL;
19856 unsigned int width, height, depth, row_pitch = 0, slice_pitch = 0;
19858 for (f = 0; f < (texture_types[t].type == D3DRTYPE_CUBETEXTURE ? 6 : 1); ++f)
19860 width = tests[i].src_width;
19861 height = texture_types[t].type != D3DRTYPE_CUBETEXTURE ? tests[i].src_height : tests[i].src_width;
19862 depth = texture_types[t].type == D3DRTYPE_VOLUMETEXTURE ? width : 1;
19864 for (l = 0; l < tests[i].src_levels; ++l)
19866 switch (texture_types[t].type)
19868 case D3DRTYPE_TEXTURE:
19869 hr = IDirect3DTexture9_LockRect((IDirect3DTexture9 *)src,
19870 l, &locked_rect, NULL, 0);
19871 ptr = locked_rect.pBits;
19872 row_pitch = locked_rect.Pitch / sizeof(*ptr);
19873 break;
19874 case D3DRTYPE_CUBETEXTURE:
19875 hr = IDirect3DCubeTexture9_LockRect((IDirect3DCubeTexture9 *)src,
19876 f, l, &locked_rect, NULL, 0);
19877 ptr = locked_rect.pBits;
19878 row_pitch = locked_rect.Pitch / sizeof(*ptr);
19879 break;
19880 case D3DRTYPE_VOLUMETEXTURE:
19881 hr = IDirect3DVolumeTexture9_LockBox((IDirect3DVolumeTexture9 *)src,
19882 l, &locked_box, NULL, 0);
19883 ptr = locked_box.pBits;
19884 row_pitch = locked_box.RowPitch / sizeof(*ptr);
19885 slice_pitch = locked_box.SlicePitch / sizeof(*ptr);
19886 break;
19887 default:
19888 trace("Unexpected resource type.\n");
19890 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
19892 for (z = 0; z < depth; ++z)
19894 for (y = 0; y < height; ++y)
19896 for (x = 0; x < width; ++x)
19898 ptr[z * slice_pitch + y * row_pitch + x] = 0xff000000
19899 | (DWORD)(x / (width - 1.0f) * 255.0f) << 16
19900 | (DWORD)(y / (height - 1.0f) * 255.0f) << 8;
19905 switch (texture_types[t].type)
19907 case D3DRTYPE_TEXTURE:
19908 hr = IDirect3DTexture9_UnlockRect((IDirect3DTexture9 *)src, l);
19909 break;
19910 case D3DRTYPE_CUBETEXTURE:
19911 hr = IDirect3DCubeTexture9_UnlockRect((IDirect3DCubeTexture9 *)src, f, l);
19912 break;
19913 case D3DRTYPE_VOLUMETEXTURE:
19914 hr = IDirect3DVolumeTexture9_UnlockBox((IDirect3DVolumeTexture9 *)src, l);
19915 break;
19916 default:
19917 trace("Unexpected resource type.\n");
19919 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
19921 width >>= 1;
19922 if (!width)
19923 width = 1;
19924 height >>= 1;
19925 if (!height)
19926 height = 1;
19927 depth >>= 1;
19928 if (!depth)
19929 depth = 1;
19934 hr = IDirect3DDevice9_UpdateTexture(device, src, dst);
19935 if (FAILED(hr))
19937 todo_wine ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u, %u.\n", hr, t, i);
19938 IDirect3DBaseTexture9_Release(src);
19939 IDirect3DBaseTexture9_Release(dst);
19940 continue;
19942 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u, %u.\n", hr, t, i);
19944 if (do_visual_test)
19946 hr = IDirect3DDevice9_SetTexture(device, 0, dst);
19947 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
19949 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 1.0f, 0);
19950 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19952 hr = IDirect3DDevice9_BeginScene(device);
19953 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19954 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
19955 texture_types[t].quad, texture_types[t].vertex_size);
19956 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19957 hr = IDirect3DDevice9_EndScene(device);
19958 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19960 color = getPixelColor(device, 320, 240);
19961 ok (color_match(color, 0x007f7f00, 3) || broken(tests[i].broken)
19962 || broken(color == 0x00adbeef), /* WARP device often just breaks down. */
19963 "Got unexpected color 0x%08x, case %u, %u.\n", color, t, i);
19966 IDirect3DBaseTexture9_Release(src);
19967 IDirect3DBaseTexture9_Release(dst);
19970 refcount = IDirect3DDevice9_Release(device);
19971 ok(!refcount, "Device has %u references left.\n", refcount);
19972 IDirect3D9_Release(d3d9);
19973 DestroyWindow(window);
19976 static void test_depthbias(void)
19978 IDirect3DDevice9 *device;
19979 IDirect3D9 *d3d;
19980 IDirect3DSurface9 *ds;
19981 D3DCAPS9 caps;
19982 D3DCOLOR color;
19983 ULONG refcount;
19984 HWND window;
19985 HRESULT hr;
19986 unsigned int i;
19987 static const D3DFORMAT formats[] =
19989 D3DFMT_D16, D3DFMT_D24X8, D3DFMT_D32, D3DFMT_D24S8, MAKEFOURCC('I','N','T','Z'),
19991 /* The scaling factor detection function detects the wrong factor for
19992 * float formats on Nvidia, therefore the following tests are disabled.
19993 * The wined3d function detects 2^23 like for fixed point formats but
19994 * the test needs 2^22 to pass.
19996 * AMD GPUs need a different scaling factor for float depth buffers
19997 * (2^24) than fixed point (2^23), but the wined3d detection function
19998 * works there, producing the right result in the test.
20000 * D3DFMT_D32F_LOCKABLE, D3DFMT_D24FS8,
20004 static const struct
20006 struct vec3 position;
20008 quad[] =
20010 {{-1.0f, -1.0f, 0.0f}},
20011 {{-1.0f, 1.0f, 0.0f}},
20012 {{ 1.0f, -1.0f, 1.0f}},
20013 {{ 1.0f, 1.0f, 1.0f}},
20015 union
20017 float f;
20018 DWORD d;
20019 } conv;
20021 window = create_window();
20022 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20023 ok(!!d3d, "Failed to create a D3D object.\n");
20024 if (!(device = create_device(d3d, window, window, TRUE)))
20026 skip("Failed to create a D3D device, skipping tests.\n");
20027 goto done;
20030 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
20031 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
20032 if (!(caps.RasterCaps & D3DPRASTERCAPS_DEPTHBIAS))
20034 IDirect3DDevice9_Release(device);
20035 skip("D3DPRASTERCAPS_DEPTHBIAS not supported.\n");
20036 goto done;
20039 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
20040 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
20041 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
20042 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
20043 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
20044 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
20045 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
20046 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
20047 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
20048 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
20050 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
20052 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20053 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, formats[i])))
20055 skip("Depth format %u not supported, skipping.\n", formats[i]);
20056 continue;
20059 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, formats[i],
20060 D3DMULTISAMPLE_NONE, 0, FALSE, &ds, NULL);
20061 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
20062 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
20063 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
20064 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 0.5f, 0);
20065 ok(SUCCEEDED(hr), "Failed to clear %08x\n", hr);
20067 hr = IDirect3DDevice9_BeginScene(device);
20068 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
20070 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x00ff0000);
20071 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20072 conv.f = -0.2f;
20073 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
20074 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20075 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20076 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20078 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
20079 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20080 conv.f = 0.0f;
20081 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
20082 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20083 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20084 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20086 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x000000ff);
20087 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20088 conv.f = 0.2f;
20089 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
20090 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20091 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20092 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20094 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x00ffffff);
20095 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20096 conv.f = 0.4f;
20097 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
20098 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20099 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20100 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20102 color = getPixelColor(device, 61, 240);
20103 ok(color_match(color, 0x00ffffff, 1), "Got unexpected color %08x at x=62, format %u.\n", color, formats[i]);
20104 color = getPixelColor(device, 65, 240);
20106 /* The broken results are for the WARP driver on the testbot. It seems to initialize
20107 * a scaling factor based on the first depth format that is used. Other formats with
20108 * a different depth size then render incorrectly. */
20109 ok(color_match(color, 0x000000ff, 1) || broken(color_match(color, 0x00ffffff, 1)),
20110 "Got unexpected color %08x at x=64, format %u.\n", color, formats[i]);
20111 color = getPixelColor(device, 190, 240);
20112 ok(color_match(color, 0x000000ff, 1) || broken(color_match(color, 0x00ffffff, 1)),
20113 "Got unexpected color %08x at x=190, format %u.\n", color, formats[i]);
20115 color = getPixelColor(device, 194, 240);
20116 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ffffff, 1)),
20117 "Got unexpected color %08x at x=194, format %u.\n", color, formats[i]);
20118 color = getPixelColor(device, 318, 240);
20119 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ffffff, 1)),
20120 "Got unexpected color %08x at x=318, format %u.\n", color, formats[i]);
20122 color = getPixelColor(device, 322, 240);
20123 ok(color_match(color, 0x00ff0000, 1) || broken(color_match(color, 0x00000000, 1)),
20124 "Got unexpected color %08x at x=322, format %u.\n", color, formats[i]);
20125 color = getPixelColor(device, 446, 240);
20126 ok(color_match(color, 0x00ff0000, 1) || broken(color_match(color, 0x00000000, 1)),
20127 "Got unexpected color %08x at x=446, format %u.\n", color, formats[i]);
20129 color = getPixelColor(device, 450, 240);
20130 ok(color_match(color, 0x00000000, 1), "Got unexpected color %08x at x=446, format %u.\n", color, formats[i]);
20132 hr = IDirect3DDevice9_EndScene(device);
20133 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
20135 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20136 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
20137 IDirect3DSurface9_Release(ds);
20140 refcount = IDirect3DDevice9_Release(device);
20141 ok(!refcount, "Device has %u references left.\n", refcount);
20143 done:
20144 IDirect3D9_Release(d3d);
20145 DestroyWindow(window);
20148 static void test_flip(void)
20150 IDirect3DDevice9 *device;
20151 IDirect3D9 *d3d;
20152 ULONG refcount;
20153 HWND window;
20154 HRESULT hr;
20155 IDirect3DSurface9 *back_buffers[3], *test_surface;
20156 unsigned int i;
20157 D3DCOLOR color;
20158 D3DPRESENT_PARAMETERS present_parameters = {0};
20160 window = create_window();
20161 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20162 ok(!!d3d, "Failed to create a D3D object.\n");
20164 present_parameters.BackBufferWidth = 640;
20165 present_parameters.BackBufferHeight = 480;
20166 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
20167 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
20168 present_parameters.hDeviceWindow = window;
20169 present_parameters.Windowed = TRUE;
20170 present_parameters.BackBufferCount = 3;
20171 present_parameters.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
20172 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20173 window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
20174 if (!device)
20176 skip("Failed to create a D3D device, skipping tests.\n");
20177 IDirect3D9_Release(d3d);
20178 DestroyWindow(window);
20179 return;
20182 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
20184 hr = IDirect3DDevice9_GetBackBuffer(device, 0, i, D3DBACKBUFFER_TYPE_MONO, &back_buffers[i]);
20185 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
20187 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &test_surface);
20188 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
20189 ok(test_surface == back_buffers[0], "Expected render target %p, got %p.\n", back_buffers[0], test_surface);
20190 IDirect3DSurface9_Release(test_surface);
20192 hr = IDirect3DDevice9_SetRenderTarget(device, 0, back_buffers[2]);
20193 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
20195 hr = IDirect3DDevice9_ColorFill(device, back_buffers[0], NULL, 0xffff0000);
20196 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x.\n", hr);
20197 hr = IDirect3DDevice9_ColorFill(device, back_buffers[1], NULL, 0xff00ff00);
20198 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x.\n", hr);
20199 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
20200 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
20202 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20203 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20205 /* Render target is unmodified. */
20206 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &test_surface);
20207 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
20208 ok(test_surface == back_buffers[2], "Expected render target %p, got %p.\n", back_buffers[2], test_surface);
20209 IDirect3DSurface9_Release(test_surface);
20211 /* Backbuffer surface pointers are unmodified */
20212 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
20214 hr = IDirect3DDevice9_GetBackBuffer(device, 0, i, D3DBACKBUFFER_TYPE_MONO, &test_surface);
20215 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
20216 ok(test_surface == back_buffers[i], "Expected back buffer %u = %p, got %p.\n",
20217 i, back_buffers[i], test_surface);
20218 IDirect3DSurface9_Release(test_surface);
20221 /* Contents were changed. */
20222 color = getPixelColorFromSurface(back_buffers[0], 1, 1);
20223 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
20224 color = getPixelColorFromSurface(back_buffers[1], 1, 1);
20225 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
20227 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0f, 0);
20228 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
20230 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20231 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20233 color = getPixelColorFromSurface(back_buffers[0], 1, 1);
20234 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
20235 color = getPixelColorFromSurface(back_buffers[1], 1, 1);
20236 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
20238 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20239 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20241 color = getPixelColorFromSurface(back_buffers[0], 1, 1);
20242 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
20244 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
20245 IDirect3DSurface9_Release(back_buffers[i]);
20247 refcount = IDirect3DDevice9_Release(device);
20248 ok(!refcount, "Device has %u references left.\n", refcount);
20250 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20251 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
20253 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample flip test.\n");
20254 goto done;
20257 present_parameters.BackBufferCount = 2;
20258 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
20259 present_parameters.Flags = 0;
20260 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20261 window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
20263 for (i = 0; i < present_parameters.BackBufferCount; ++i)
20265 hr = IDirect3DDevice9_GetBackBuffer(device, 0, i, D3DBACKBUFFER_TYPE_MONO, &back_buffers[i]);
20266 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
20269 hr = IDirect3DDevice9_SetRenderTarget(device, 0, back_buffers[1]);
20270 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
20271 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0f, 0);
20272 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
20274 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20275 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20277 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
20278 D3DMULTISAMPLE_NONE, 0, TRUE, &test_surface, NULL);
20279 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
20280 hr = IDirect3DDevice9_StretchRect(device, back_buffers[0], NULL, test_surface, NULL, D3DTEXF_POINT);
20281 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
20283 color = getPixelColorFromSurface(test_surface, 1, 1);
20284 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
20286 IDirect3DSurface9_Release(test_surface);
20287 for (i = 0; i < present_parameters.BackBufferCount; ++i)
20288 IDirect3DSurface9_Release(back_buffers[i]);
20290 refcount = IDirect3DDevice9_Release(device);
20291 ok(!refcount, "Device has %u references left.\n", refcount);
20293 done:
20294 IDirect3D9_Release(d3d);
20295 DestroyWindow(window);
20298 static void test_uninitialized_varyings(void)
20300 static const D3DMATRIX mat =
20302 1.0f, 0.0f, 0.0f, 0.0f,
20303 0.0f, 1.0f, 0.0f, 0.0f,
20304 0.0f, 0.0f, 1.0f, 0.0f,
20305 0.0f, 0.0f, 0.0f, 1.0f,
20306 }}};
20307 static const struct vec3 quad[] =
20309 {-1.0f, -1.0f, 0.1f},
20310 {-1.0f, 1.0f, 0.1f},
20311 { 1.0f, -1.0f, 0.1f},
20312 { 1.0f, 1.0f, 0.1f},
20314 static const DWORD vs1_code[] =
20316 0xfffe0101, /* vs_1_1 */
20317 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20318 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
20319 0x0000ffff
20321 static const DWORD vs1_partial_code[] =
20323 0xfffe0101, /* vs_1_1 */
20324 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20325 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
20326 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
20327 0x00000001, 0xd0010000, 0xa0e40000, /* mov oD0.x, c0 */
20328 0x00000001, 0xd0010001, 0xa0e40000, /* mov oD1.x, c0 */
20329 0x00000001, 0xe0010000, 0xa0e40000, /* mov oT0.x, c0 */
20330 0x0000ffff
20332 static const DWORD vs2_code[] =
20334 0xfffe0200, /* vs_2_0 */
20335 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20336 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
20337 0x0000ffff
20339 static const DWORD vs2_partial_code[] =
20341 0xfffe0200, /* vs_2_0 */
20342 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20343 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
20344 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
20345 0x02000001, 0xd0010000, 0xa0e40000, /* mov oD0.x, c0 */
20346 0x02000001, 0xd0010001, 0xa0e40000, /* mov oD1.x, c0 */
20347 0x02000001, 0xe0010000, 0xa0e40000, /* mov oT0.x, c0 */
20348 0x0000ffff
20350 static const DWORD vs3_code[] =
20352 0xfffe0300, /* vs_3_0 */
20353 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20354 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
20355 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
20356 0x0000ffff
20358 static const DWORD vs3_partial_code[] =
20360 0xfffe0300, /* vs_3_0 */
20361 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20362 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
20363 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
20364 0x0200001f, 0x8001000a, 0xe00f0002, /* dcl_color1 o2 */
20365 0x0200001f, 0x80000005, 0xe00f0003, /* dcl_texcoord0 o3 */
20366 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
20367 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
20368 0x02000001, 0xe0010001, 0xa0e40000, /* mov o1.x, c0 */
20369 0x02000001, 0xe0010002, 0xa0e40000, /* mov o2.x, c0 */
20370 0x02000001, 0xe0010003, 0xa0e40000, /* mov o3.x, c0 */
20371 0x0000ffff
20373 static const DWORD ps1_diffuse_code[] =
20375 0xffff0101, /* ps_1_1 */
20376 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
20377 0x0000ffff
20379 static const DWORD ps1_specular_code[] =
20381 0xffff0101, /* ps_1_1 */
20382 0x00000001, 0x800f0000, 0x90e40001, /* mov r0, v1 */
20383 0x0000ffff
20385 static const DWORD ps1_texcoord_code[] =
20387 0xffff0101, /* ps_1_1 */
20388 0x00000040, 0xb00f0000, /* texcoord t0 */
20389 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
20390 0x0000ffff
20392 static const DWORD ps2_diffuse_code[] =
20394 0xffff0200, /* ps_2_0 */
20395 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
20396 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
20397 0x0000ffff
20399 static const DWORD ps2_specular_code[] =
20401 0xffff0200, /* ps_2_0 */
20402 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
20403 0x02000001, 0x800f0800, 0x90e40001, /* mov oC0, v1 */
20404 0x0000ffff
20406 static const DWORD ps2_texcoord_code[] =
20408 0xffff0200, /* ps_2_0 */
20409 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
20410 0x02000001, 0x800f0800, 0xb0e40000, /* mov oC0, t0 */
20411 0x0000ffff
20413 static const DWORD ps3_diffuse_code[] =
20415 0xffff0300, /* ps_3_0 */
20416 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
20417 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
20418 0x0000ffff
20420 static const DWORD ps3_specular_code[] =
20422 0xffff0300, /* ps_3_0 */
20423 0x0200001f, 0x8001000a, 0x900f0001, /* dcl_color1 v1 */
20424 0x02000001, 0x800f0800, 0x90e40001, /* mov oC0, v1 */
20425 0x0000ffff
20427 static const DWORD ps3_texcoord_code[] =
20429 0xffff0300, /* ps_3_0 */
20430 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
20431 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
20432 0x0000ffff
20434 static const struct
20436 DWORD vs_version;
20437 const DWORD *vs;
20438 DWORD ps_version;
20439 const DWORD *ps;
20440 D3DCOLOR expected;
20441 BOOL allow_zero_alpha;
20442 BOOL allow_zero;
20443 BOOL broken_warp;
20445 /* On AMD specular color is generally initialized to 0x00000000 and texcoords to 0xff000000
20446 * while on Nvidia it's the opposite. Just allow both. */
20447 tests[] =
20449 {D3DVS_VERSION(1, 1), vs1_code, 0, NULL, 0xffffffff},
20450 { 0, NULL, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff000000, TRUE},
20451 { 0, NULL, D3DPS_VERSION(2, 0), ps2_texcoord_code, 0xff000000, TRUE},
20452 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_diffuse_code, 0xffffffff},
20453 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_specular_code, 0xff000000, TRUE, FALSE, TRUE},
20454 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff000000, TRUE},
20455 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_diffuse_code, 0xffffffff},
20456 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_specular_code, 0xff000000, TRUE, FALSE, TRUE},
20457 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_texcoord_code, 0xff000000, TRUE},
20458 {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_diffuse_code, 0xffffffff, FALSE, TRUE},
20459 {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_specular_code, 0x00000000, FALSE, FALSE, TRUE},
20460 {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_texcoord_code, 0x00000000, FALSE, FALSE, TRUE},
20461 {D3DVS_VERSION(1, 1), vs1_partial_code, 0, NULL, 0xff7fffff, FALSE, FALSE, TRUE},
20462 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_diffuse_code, 0xff7fffff, FALSE, FALSE, TRUE},
20463 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_specular_code, 0xff7f0000, TRUE},
20464 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff7f0000, TRUE},
20465 {D3DVS_VERSION(2, 0), vs2_partial_code, D3DPS_VERSION(2, 0), ps2_diffuse_code, 0xff7fffff, FALSE, FALSE, TRUE},
20466 {D3DVS_VERSION(2, 0), vs2_partial_code, D3DPS_VERSION(2, 0), ps2_specular_code, 0xff7f0000, TRUE},
20467 {D3DVS_VERSION(2, 0), vs2_partial_code, D3DPS_VERSION(2, 0), ps2_texcoord_code, 0xff7f0000, TRUE},
20468 /* Fails on Radeon HD 2600 with 0x008000ff aka nonsensical color. */
20469 /* {D3DVS_VERSION(3, 0), vs3_partial_code, D3DPS_VERSION(3, 0), ps3_diffuse_code, 0xff7fffff, TRUE}, */
20470 /* Randomly fails on Radeon HD 2600. */
20471 /* {D3DVS_VERSION(3, 0), vs3_partial_code, D3DPS_VERSION(3, 0), ps3_specular_code, 0x007f0000}, */
20472 {D3DVS_VERSION(3, 0), vs3_partial_code, D3DPS_VERSION(3, 0), ps3_texcoord_code, 0xff7f0000, TRUE},
20474 IDirect3DDevice9 *device;
20475 IDirect3D9 *d3d;
20476 HWND window;
20477 HRESULT hr;
20478 D3DADAPTER_IDENTIFIER9 identifier;
20479 IDirect3DSurface9 *backbuffer;
20480 struct surface_readback rb;
20481 IDirect3DVertexShader9 *vs;
20482 IDirect3DPixelShader9 *ps;
20483 unsigned int i;
20484 ULONG refcount;
20485 D3DCAPS9 caps;
20486 D3DCOLOR color;
20487 BOOL warp;
20489 window = create_window();
20490 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20491 ok(!!d3d, "Failed to create a D3D object.\n");
20492 if (!(device = create_device(d3d, window, window, TRUE)))
20494 skip("Failed to create a D3D device, skipping tests.\n");
20495 IDirect3D9_Release(d3d);
20496 DestroyWindow(window);
20497 return;
20500 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
20501 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
20502 warp = adapter_is_warp(&identifier);
20504 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
20505 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
20507 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
20508 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
20510 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
20511 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
20512 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
20513 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
20514 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
20515 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
20516 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
20517 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
20518 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
20519 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
20520 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
20521 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
20522 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
20523 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#x.\n", hr);
20524 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
20525 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
20527 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
20528 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
20530 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
20532 if (caps.VertexShaderVersion < tests[i].vs_version
20533 || caps.PixelShaderVersion < tests[i].ps_version)
20535 skip("Vertex / pixel shader version not supported, skipping test %u.\n", i);
20536 continue;
20538 if (tests[i].vs)
20540 hr = IDirect3DDevice9_CreateVertexShader(device, tests[i].vs, &vs);
20541 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
20543 else
20545 vs = NULL;
20547 if (tests[i].ps)
20549 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].ps, &ps);
20550 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
20552 else
20554 ps = NULL;
20557 hr = IDirect3DDevice9_SetVertexShader(device, vs);
20558 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
20559 hr = IDirect3DDevice9_SetPixelShader(device, ps);
20560 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
20562 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
20563 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
20565 hr = IDirect3DDevice9_BeginScene(device);
20566 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
20568 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
20569 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20571 hr = IDirect3DDevice9_EndScene(device);
20572 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
20574 get_rt_readback(backbuffer, &rb);
20575 color = get_readback_color(&rb, 320, 240);
20576 ok(color_match(color, tests[i].expected, 1)
20577 || (tests[i].allow_zero_alpha && color_match(color, tests[i].expected & 0x00ffffff, 1))
20578 || (tests[i].allow_zero && !color) || (broken(warp && tests[i].broken_warp)),
20579 "Got unexpected color 0x%08x, case %u.\n", color, i);
20580 release_surface_readback(&rb);
20582 if (vs)
20583 IDirect3DVertexShader9_Release(vs);
20584 if (ps)
20585 IDirect3DVertexShader9_Release(ps);
20588 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20589 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20591 IDirect3DSurface9_Release(backbuffer);
20592 refcount = IDirect3DDevice9_Release(device);
20593 ok(!refcount, "Device has %u references left.\n", refcount);
20594 IDirect3D9_Release(d3d);
20595 DestroyWindow(window);
20598 static void test_multisample_init(void)
20600 IDirect3DDevice9 *device;
20601 IDirect3D9 *d3d;
20602 IDirect3DSurface9 *back, *multi;
20603 ULONG refcount;
20604 HWND window;
20605 HRESULT hr;
20606 D3DCOLOR color;
20607 unsigned int x, y;
20608 struct surface_readback rb;
20609 BOOL all_zero = TRUE;
20611 window = create_window();
20612 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20613 ok(!!d3d, "Failed to create a D3D object.\n");
20615 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20616 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
20618 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample init test.\n");
20619 goto done;
20622 if (!(device = create_device(d3d, window, window, TRUE)))
20624 skip("Failed to create a D3D device, skipping tests.\n");
20625 goto done;
20628 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &back);
20629 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
20630 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
20631 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &multi, NULL);
20632 ok(SUCCEEDED(hr), "Failed to create multisampled render target, hr %#x.\n", hr);
20634 hr = IDirect3DDevice9_StretchRect(device, multi, NULL, back, NULL, D3DTEXF_POINT);
20635 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
20637 get_rt_readback(back, &rb);
20638 for (y = 0; y < 480; ++y)
20640 for (x = 0; x < 640; x++)
20642 color = get_readback_color(&rb, x, y);
20643 if (!color_match(color, 0x00000000, 0))
20645 all_zero = FALSE;
20646 break;
20649 if (!all_zero)
20650 break;
20652 release_surface_readback(&rb);
20653 ok(all_zero, "Got unexpected color 0x%08x, position %ux%u.\n", color, x, y);
20655 IDirect3DSurface9_Release(multi);
20656 IDirect3DSurface9_Release(back);
20658 refcount = IDirect3DDevice9_Release(device);
20659 ok(!refcount, "Device has %u references left.\n", refcount);
20661 done:
20662 IDirect3D9_Release(d3d);
20663 DestroyWindow(window);
20666 static void test_texture_blending(void)
20668 #define STATE_END() {0xffffffff, 0xffffffff}
20669 #define IS_STATE_END(s) (s.name == 0xffffffff && s.value == 0xffffffff)
20671 IDirect3DTexture9 *texture_bumpmap, *texture_red;
20672 IDirect3DSurface9 *backbuffer;
20673 struct surface_readback rb;
20674 D3DLOCKED_RECT locked_rect;
20675 IDirect3DDevice9 *device;
20676 unsigned int i, j, k;
20677 IDirect3D9 *d3d;
20678 D3DCOLOR color;
20679 ULONG refcount;
20680 D3DCAPS9 caps;
20681 HWND window;
20682 HRESULT hr;
20684 static const struct
20686 struct vec3 position;
20687 DWORD diffuse;
20689 quad[] =
20691 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
20692 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
20693 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
20694 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
20697 static const float bumpenvmat[4] = {1.0f, 1.0f, 0.0f, 0.0f};
20699 struct texture_stage_state
20701 D3DTEXTURESTAGESTATETYPE name;
20702 DWORD value;
20705 struct texture_stage
20707 enum
20709 TEXTURE_INVALID,
20710 TEXTURE_NONE,
20711 TEXTURE_BUMPMAP,
20712 TEXTURE_RED,
20714 texture;
20715 struct texture_stage_state state[20];
20718 static const struct texture_stage default_stage_state =
20720 TEXTURE_NONE,
20722 {D3DTSS_COLOROP, D3DTOP_DISABLE},
20723 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
20724 {D3DTSS_COLORARG2, D3DTA_CURRENT},
20725 {D3DTSS_ALPHAOP, D3DTOP_DISABLE},
20726 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
20727 {D3DTSS_ALPHAARG2, D3DTA_CURRENT},
20728 {D3DTSS_BUMPENVMAT00, 0},
20729 {D3DTSS_BUMPENVMAT01, 0},
20730 {D3DTSS_BUMPENVMAT10, 0},
20731 {D3DTSS_BUMPENVMAT11, 0},
20732 {D3DTSS_BUMPENVLSCALE, 0},
20733 {D3DTSS_BUMPENVLOFFSET, 0},
20734 {D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE},
20735 {D3DTSS_COLORARG0, D3DTA_CURRENT},
20736 {D3DTSS_ALPHAARG0, D3DTA_CURRENT},
20737 {D3DTSS_RESULTARG, D3DTA_CURRENT},
20738 {D3DTSS_CONSTANT, 0},
20739 STATE_END(),
20743 const struct test
20745 DWORD tex_op_caps;
20746 D3DCOLOR expected_color;
20747 struct texture_stage stage[8];
20749 tests[] =
20752 D3DTEXOPCAPS_DISABLE,
20753 0x80ffff02,
20756 TEXTURE_NONE,
20758 STATE_END(),
20764 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
20765 0x80ffff02,
20768 TEXTURE_NONE,
20770 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
20771 {D3DTSS_COLORARG1, D3DTA_CURRENT},
20772 STATE_END(),
20775 {TEXTURE_INVALID}
20779 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
20780 0x80ffff02,
20783 TEXTURE_NONE,
20785 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
20786 {D3DTSS_COLORARG1, D3DTA_CURRENT},
20787 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20788 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
20789 STATE_END(),
20795 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
20796 0x80ffff02,
20799 TEXTURE_NONE,
20801 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
20802 {D3DTSS_COLORARG1, D3DTA_DIFFUSE},
20803 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20804 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
20805 STATE_END(),
20811 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
20812 0x00000000,
20815 TEXTURE_NONE,
20817 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
20818 {D3DTSS_COLORARG1, D3DTA_TEMP},
20819 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20820 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
20821 STATE_END(),
20827 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_SUBTRACT,
20828 0x80f0f000,
20831 TEXTURE_NONE,
20833 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
20834 {D3DTSS_COLORARG1, D3DTA_CURRENT},
20835 STATE_END(),
20839 TEXTURE_NONE,
20841 {D3DTSS_COLOROP, D3DTOP_SUBTRACT},
20842 {D3DTSS_COLORARG1, D3DTA_CURRENT},
20843 {D3DTSS_COLORARG2, D3DTA_CONSTANT},
20844 {D3DTSS_CONSTANT, 0x0f0f0f0f},
20845 STATE_END(),
20848 {TEXTURE_INVALID}
20852 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_SUBTRACT,
20853 0x71f0f000,
20856 TEXTURE_NONE,
20858 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
20859 {D3DTSS_COLORARG1, D3DTA_CURRENT},
20860 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20861 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
20862 STATE_END(),
20866 TEXTURE_NONE,
20868 {D3DTSS_COLOROP, D3DTOP_SUBTRACT},
20869 {D3DTSS_COLORARG1, D3DTA_CURRENT},
20870 {D3DTSS_COLORARG2, D3DTA_CONSTANT},
20871 {D3DTSS_ALPHAOP, D3DTOP_SUBTRACT},
20872 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
20873 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
20874 {D3DTSS_CONSTANT, 0x0f0f0f0f},
20875 STATE_END(),
20878 {TEXTURE_INVALID}
20883 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
20884 0x80ff0000,
20887 TEXTURE_BUMPMAP,
20889 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
20890 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
20891 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
20892 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
20893 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
20894 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20895 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
20896 STATE_END(),
20901 TEXTURE_RED,
20903 {D3DTSS_COLOROP, D3DTOP_MODULATE},
20904 STATE_END(),
20907 {TEXTURE_INVALID}
20911 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
20912 0x80ff0000,
20915 TEXTURE_BUMPMAP,
20917 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
20918 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
20919 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
20920 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
20921 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
20922 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20923 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
20924 STATE_END(),
20928 TEXTURE_RED,
20930 {D3DTSS_COLOROP, D3DTOP_MODULATE},
20931 STATE_END(),
20934 {TEXTURE_INVALID}
20938 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
20939 0x80ff0000,
20942 TEXTURE_BUMPMAP,
20944 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
20945 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
20946 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
20947 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
20948 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
20949 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20950 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
20951 STATE_END(),
20955 TEXTURE_RED,
20957 {D3DTSS_COLOROP, D3DTOP_MODULATE},
20958 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20959 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
20960 STATE_END(),
20963 {TEXTURE_INVALID}
20967 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
20968 0x00ff0000,
20971 TEXTURE_BUMPMAP,
20973 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
20974 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
20975 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
20976 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
20977 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
20978 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20979 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
20980 STATE_END(),
20984 TEXTURE_RED,
20986 {D3DTSS_COLOROP, D3DTOP_MODULATE},
20987 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
20988 {D3DTSS_COLORARG2, D3DTA_CURRENT},
20989 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20990 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
20991 STATE_END(),
20994 {TEXTURE_INVALID}
20998 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
20999 0x80ff0000,
21002 TEXTURE_BUMPMAP,
21004 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21005 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21006 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21007 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21008 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21009 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21010 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21011 STATE_END(),
21015 TEXTURE_RED,
21017 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21018 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21019 {D3DTSS_COLORARG2, D3DTA_CURRENT},
21020 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21021 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21022 STATE_END(),
21025 {TEXTURE_INVALID}
21030 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
21031 | D3DTEXOPCAPS_ADD,
21032 0x80ff0000,
21035 TEXTURE_BUMPMAP,
21037 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21038 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21039 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21040 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21041 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21042 {D3DTSS_ALPHAOP, D3DTOP_ADD},
21043 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
21044 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
21045 {D3DTSS_CONSTANT, 0x0fffffff},
21046 STATE_END(),
21050 TEXTURE_RED,
21052 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21053 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21054 {D3DTSS_COLORARG2, D3DTA_CURRENT},
21055 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21056 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21057 STATE_END(),
21060 {TEXTURE_INVALID}
21064 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
21065 | D3DTEXOPCAPS_MODULATE2X,
21066 0x80ff0000,
21069 TEXTURE_BUMPMAP,
21071 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21072 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21073 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21074 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21075 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21076 {D3DTSS_ALPHAOP, D3DTOP_MODULATE2X},
21077 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
21078 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
21079 {D3DTSS_CONSTANT, 0x01ffffff},
21080 STATE_END(),
21084 TEXTURE_RED,
21086 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21087 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21088 {D3DTSS_COLORARG2, D3DTA_CURRENT},
21089 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21090 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21091 STATE_END(),
21094 {TEXTURE_INVALID}
21098 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
21099 | D3DTEXOPCAPS_MODULATE2X,
21100 0x80ffff00,
21103 TEXTURE_BUMPMAP,
21105 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21106 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21107 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21108 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21109 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21110 {D3DTSS_ALPHAOP, D3DTOP_MODULATE2X},
21111 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21112 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
21113 {D3DTSS_CONSTANT, 0x01ffffff},
21114 STATE_END(),
21118 TEXTURE_RED,
21120 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21121 {D3DTSS_COLORARG1, D3DTA_CURRENT},
21122 {D3DTSS_COLORARG2, D3DTA_CURRENT},
21123 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21124 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21125 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
21126 {D3DTSS_ALPHAARG0, D3DTA_CONSTANT},
21127 STATE_END(),
21130 {TEXTURE_INVALID}
21134 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
21135 0x01234567,
21138 TEXTURE_NONE,
21140 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21141 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
21142 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21143 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
21144 {D3DTSS_RESULTARG, D3DTA_TEMP},
21145 {D3DTSS_CONSTANT, 0x01234567},
21146 STATE_END(),
21150 TEXTURE_BUMPMAP,
21152 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21153 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21154 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21155 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21156 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21157 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21158 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21159 {D3DTSS_RESULTARG, D3DTA_TEMP},
21160 STATE_END(),
21164 TEXTURE_RED,
21166 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21167 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21168 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21169 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
21170 STATE_END(),
21174 TEXTURE_NONE,
21176 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21177 {D3DTSS_COLORARG1, D3DTA_TEMP},
21178 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21179 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21180 STATE_END(),
21183 {TEXTURE_INVALID}
21187 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
21188 0x00234567,
21191 TEXTURE_NONE,
21193 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21194 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
21195 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21196 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
21197 {D3DTSS_RESULTARG, D3DTA_TEMP},
21198 {D3DTSS_CONSTANT, 0x01234567},
21199 STATE_END(),
21203 TEXTURE_BUMPMAP,
21205 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21206 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21207 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21208 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21209 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21210 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21211 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21212 STATE_END(),
21216 TEXTURE_RED,
21218 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21219 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21220 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21221 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
21222 STATE_END(),
21226 TEXTURE_NONE,
21228 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21229 {D3DTSS_COLORARG1, D3DTA_TEMP},
21230 STATE_END(),
21233 {TEXTURE_INVALID}
21237 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
21238 0x01234567,
21241 TEXTURE_NONE,
21243 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21244 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
21245 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21246 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
21247 {D3DTSS_RESULTARG, D3DTA_TEMP},
21248 {D3DTSS_CONSTANT, 0x01234567},
21249 STATE_END(),
21253 TEXTURE_BUMPMAP,
21255 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21256 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21257 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21258 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21259 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21260 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21261 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21262 {D3DTSS_RESULTARG, D3DTA_TEMP},
21263 STATE_END(),
21267 TEXTURE_RED,
21269 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21270 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21271 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21272 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
21273 STATE_END(),
21277 TEXTURE_NONE,
21279 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21280 {D3DTSS_COLORARG1, D3DTA_TEMP},
21281 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21282 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21283 STATE_END(),
21286 {TEXTURE_INVALID}
21290 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
21291 0x01234567,
21294 TEXTURE_NONE,
21296 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21297 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
21298 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21299 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
21300 {D3DTSS_RESULTARG, D3DTA_CURRENT},
21301 {D3DTSS_CONSTANT, 0x01234567},
21302 STATE_END(),
21306 TEXTURE_BUMPMAP,
21308 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21309 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21310 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21311 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21312 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21313 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21314 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21315 {D3DTSS_RESULTARG, D3DTA_TEMP},
21316 STATE_END(),
21320 TEXTURE_RED,
21322 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21323 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21324 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21325 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
21326 {D3DTSS_RESULTARG, D3DTA_TEMP},
21327 STATE_END(),
21331 TEXTURE_NONE,
21333 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21334 {D3DTSS_COLORARG1, D3DTA_CURRENT},
21335 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21336 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21337 {D3DTSS_RESULTARG, D3DTA_CURRENT},
21338 STATE_END(),
21341 {TEXTURE_INVALID}
21346 window = create_window();
21347 d3d = Direct3DCreate9(D3D_SDK_VERSION);
21348 ok(!!d3d, "Failed to create a D3D object.\n");
21349 if (!(device = create_device(d3d, window, window, TRUE)))
21351 skip("Failed to create a D3D device.\n");
21352 goto done;
21355 memset(&caps, 0, sizeof(caps));
21356 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
21357 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr %#x.\n", hr);
21359 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
21361 skip("D3DPMISCCAPS_TSSARGTEMP not supported.\n");
21362 IDirect3DDevice9_Release(device);
21363 goto done;
21366 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_PERSTAGECONSTANT))
21368 skip("D3DPMISCCAPS_PERSTAGECONSTANT not supported.\n");
21369 IDirect3DDevice9_Release(device);
21370 goto done;
21373 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
21374 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_V8U8)))
21376 skip("D3DFMT_V8U8 not supported for legacy bump mapping.\n");
21377 IDirect3DDevice9_Release(device);
21378 goto done;
21381 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
21382 ok(hr == D3D_OK, "Can't get back buffer, hr %#x.\n", hr);
21384 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture_bumpmap, NULL);
21385 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr %#x.\n", hr);
21386 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture_red, NULL);
21387 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr %#x.\n", hr);
21389 memset(&locked_rect, 0, sizeof(locked_rect));
21390 hr = IDirect3DTexture9_LockRect(texture_bumpmap, 0, &locked_rect, NULL, 0);
21391 ok(SUCCEEDED(hr), "LockRect failed, hr %#x.\n", hr);
21392 *((WORD *)locked_rect.pBits) = 0xff00;
21393 hr = IDirect3DTexture9_UnlockRect(texture_bumpmap, 0);
21394 ok(SUCCEEDED(hr), "UnlockRect failed, hr %#x.\n", hr);
21396 memset(&locked_rect, 0, sizeof(locked_rect));
21397 hr = IDirect3DTexture9_LockRect(texture_red, 0, &locked_rect, NULL, 0);
21398 ok(SUCCEEDED(hr), "LockRect failed, hr %#x.\n", hr);
21399 *((DWORD *)locked_rect.pBits) = 0x00ff0000;
21400 hr = IDirect3DTexture9_UnlockRect(texture_red, 0);
21401 ok(SUCCEEDED(hr), "UnlockRect failed, hr %#x.\n", hr);
21403 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
21404 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
21405 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
21406 ok(hr == D3D_OK, "Failed to disable lighting, hr %#x.\n", hr);
21408 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
21410 const struct test *current_test = &tests[i];
21412 if ((caps.TextureOpCaps & current_test->tex_op_caps) != current_test->tex_op_caps)
21414 skip("Texture operations %#x not supported.\n", current_test->tex_op_caps);
21415 continue;
21418 for (j = 0; j < caps.MaxTextureBlendStages; ++j)
21420 IDirect3DTexture9 *current_texture = NULL;
21422 for (k = 0; !IS_STATE_END(default_stage_state.state[k]); ++k)
21424 hr = IDirect3DDevice9_SetTextureStageState(device, j,
21425 default_stage_state.state[k].name, default_stage_state.state[k].value);
21426 ok(SUCCEEDED(hr), "Test %u: SetTextureStageState failed, hr %#x.\n", i, hr);
21429 if (current_test->stage[j].texture != TEXTURE_INVALID)
21431 const struct texture_stage_state *current_state = current_test->stage[j].state;
21433 switch (current_test->stage[j].texture)
21435 case TEXTURE_RED:
21436 current_texture = texture_red;
21437 break;
21438 case TEXTURE_BUMPMAP:
21439 current_texture = texture_bumpmap;
21440 break;
21441 default:
21442 current_texture = NULL;
21443 break;
21446 for (k = 0; !IS_STATE_END(current_state[k]); ++k)
21448 hr = IDirect3DDevice9_SetTextureStageState(device, j,
21449 current_state[k].name, current_state[k].value);
21450 ok(SUCCEEDED(hr), "Test %u: SetTextureStageState failed, hr %#x.\n", i, hr);
21454 hr = IDirect3DDevice9_SetTexture(device, j, (IDirect3DBaseTexture9 *)current_texture);
21455 ok(SUCCEEDED(hr), "Test %u: SetTexture failed, hr %#x.\n", i, hr);
21458 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
21459 ok(hr == D3D_OK, "Test %u: IDirect3DDevice9_Clear failed, hr %#x.\n", i, hr);
21461 hr = IDirect3DDevice9_BeginScene(device);
21462 ok(SUCCEEDED(hr), "Test %u: BeginScene failed, hr %#x.\n", i, hr);
21463 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
21464 ok(SUCCEEDED(hr), "Test %u: DrawPrimitiveUP failed, hr %#x.\n", i, hr);
21465 hr = IDirect3DDevice9_EndScene(device);
21466 ok(SUCCEEDED(hr), "Test %u: EndScene failed, hr %#x.\n", i, hr);
21468 get_rt_readback(backbuffer, &rb);
21469 color = get_readback_color(&rb, 320, 240);
21470 ok(color_match(color, current_test->expected_color, 1),
21471 "Test %u: Got color 0x%08x, expected 0x%08x.\n", i, color, current_test->expected_color);
21472 release_surface_readback(&rb);
21473 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21474 ok(SUCCEEDED(hr), "Test %u: Present failed, hr %#x.\n", i, hr);
21477 IDirect3DTexture9_Release(texture_bumpmap);
21478 IDirect3DTexture9_Release(texture_red);
21479 IDirect3DSurface9_Release(backbuffer);
21480 refcount = IDirect3DDevice9_Release(device);
21481 ok(!refcount, "Device has %u references left.\n", refcount);
21482 done:
21483 IDirect3D9_Release(d3d);
21484 DestroyWindow(window);
21487 static void test_color_clamping(void)
21489 static const D3DMATRIX mat =
21491 1.0f, 0.0f, 0.0f, 0.0f,
21492 0.0f, 1.0f, 0.0f, 0.0f,
21493 0.0f, 0.0f, 1.0f, 0.0f,
21494 0.0f, 0.0f, 0.0f, 1.0f,
21495 }}};
21496 static const struct vec3 quad[] =
21498 {-1.0f, -1.0f, 0.1f},
21499 {-1.0f, 1.0f, 0.1f},
21500 { 1.0f, -1.0f, 0.1f},
21501 { 1.0f, 1.0f, 0.1f},
21503 static const DWORD vs1_code[] =
21505 0xfffe0101, /* vs_1_1 */
21506 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
21507 0x00000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
21508 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
21509 0x00000002, 0xd00f0000, 0xa0e40000, 0xa0e40000, /* add oD0, c0, c0 */
21510 0x00000002, 0xd00f0001, 0xa0e40000, 0xa0e40000, /* add oD1, c0, c0 */
21511 0x0000ffff
21513 static const DWORD vs2_code[] =
21515 0xfffe0200, /* vs_2_0 */
21516 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
21517 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
21518 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
21519 0x03000002, 0xd00f0000, 0xa0e40000, 0xa0e40000, /* add oD0, c0, c0 */
21520 0x03000002, 0xd00f0001, 0xa0e40000, 0xa0e40000, /* add oD1, c0, c0 */
21521 0x0000ffff
21523 static const DWORD vs3_code[] =
21525 0xfffe0300, /* vs_3_0 */
21526 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
21527 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
21528 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
21529 0x0200001f, 0x8001000a, 0xe00f0002, /* dcl_color1 o2 */
21530 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
21531 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
21532 0x03000002, 0xe00f0001, 0xa0e40000, 0xa0e40000, /* add o1, c0, c0 */
21533 0x03000002, 0xe00f0002, 0xa0e40000, 0xa0e40000, /* add o2, c0, c0 */
21534 0x0000ffff
21536 static const DWORD ps1_code[] =
21538 0xffff0101, /* ps_1_1 */
21539 0x00000051, 0xa00f0000, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000, /* def c0, 0.25, 0.25, 0.25, 0.25 */
21540 0x00000002, 0x800f0000, 0x90e40000, 0x90e40001, /* add r0, v0, v1 */
21541 0x00000005, 0x800f0000, 0x80e40000, 0xa0e40000, /* mul r0, r0, c0 */
21542 0x0000ffff
21544 static const DWORD ps2_code[] =
21546 0xffff0200, /* ps_2_0 */
21547 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
21548 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
21549 0x05000051, 0xa00f0000, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000, /* def c0, 0.25, 0.25, 0.25, 0.25 */
21550 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
21551 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
21552 0x03000005, 0x800f0000, 0x80e40000, 0xa0e40000, /* mul r0, r0, c0 */
21553 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
21554 0x0000ffff
21556 static const DWORD ps3_code[] =
21558 0xffff0300, /* ps_3_0 */
21559 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
21560 0x0200001f, 0x8001000a, 0x900f0001, /* dcl_color1 v1 */
21561 0x05000051, 0xa00f0000, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000, /* def c0, 0.25, 0.25, 0.25, 0.25 */
21562 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
21563 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
21564 0x03000005, 0x800f0800, 0x80e40000, 0xa0e40000, /* mul oC0, r0, c0 */
21565 0x0000ffff
21567 static const struct
21569 DWORD vs_version;
21570 const DWORD *vs;
21571 DWORD ps_version;
21572 const DWORD *ps;
21573 D3DCOLOR expected, broken;
21575 tests[] =
21577 {0, NULL, 0, NULL, 0x00404040},
21578 {0, NULL, D3DPS_VERSION(1, 1), ps1_code, 0x00404040, 0x00808080},
21579 {D3DVS_VERSION(1, 1), vs1_code, 0, NULL, 0x00404040},
21580 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_code, 0x007f7f7f},
21581 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_code, 0x007f7f7f},
21582 {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_code, 0x00ffffff},
21584 IDirect3DVertexShader9 *vs;
21585 IDirect3DPixelShader9 *ps;
21586 IDirect3DDevice9 *device;
21587 IDirect3D9 *d3d9;
21588 unsigned int i;
21589 ULONG refcount;
21590 D3DCOLOR color;
21591 D3DCAPS9 caps;
21592 HWND window;
21593 HRESULT hr;
21595 window = create_window();
21596 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
21597 ok(!!d3d9, "Failed to create a D3D object.\n");
21598 if (!(device = create_device(d3d9, window, window, TRUE)))
21600 skip("Failed to create a D3D device, skipping tests.\n");
21601 IDirect3D9_Release(d3d9);
21602 DestroyWindow(window);
21603 return;
21606 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
21607 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
21609 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
21610 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
21611 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
21612 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
21613 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
21614 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
21615 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
21616 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
21617 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
21618 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
21619 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
21620 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
21621 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
21622 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#x.\n", hr);
21623 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
21624 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
21625 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
21626 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
21628 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xff404040);
21629 ok(SUCCEEDED(hr), "Failed to set texture factor, hr %#x.\n", hr);
21630 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
21631 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
21632 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
21633 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
21634 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_SPECULAR);
21635 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
21636 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_MODULATE);
21637 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
21638 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
21639 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
21640 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
21641 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
21643 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
21644 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
21646 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
21648 if (caps.VertexShaderVersion < tests[i].vs_version
21649 || caps.PixelShaderVersion < tests[i].ps_version)
21651 skip("Vertex / pixel shader version not supported, skipping test %u.\n", i);
21652 continue;
21654 if (tests[i].vs)
21656 hr = IDirect3DDevice9_CreateVertexShader(device, tests[i].vs, &vs);
21657 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
21659 else
21661 vs = NULL;
21663 if (tests[i].ps)
21665 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].ps, &ps);
21666 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
21668 else
21670 ps = NULL;
21673 hr = IDirect3DDevice9_SetVertexShader(device, vs);
21674 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
21675 hr = IDirect3DDevice9_SetPixelShader(device, ps);
21676 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
21678 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
21679 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21681 hr = IDirect3DDevice9_BeginScene(device);
21682 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21684 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
21685 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
21687 hr = IDirect3DDevice9_EndScene(device);
21688 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
21690 color = getPixelColor(device, 320, 240);
21691 ok(color_match(color, tests[i].expected, 1) || broken(color_match(color, tests[i].broken, 1)),
21692 "Got unexpected color 0x%08x, case %u.\n", color, i);
21694 if (vs)
21695 IDirect3DVertexShader9_Release(vs);
21696 if (ps)
21697 IDirect3DVertexShader9_Release(ps);
21700 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21701 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
21703 refcount = IDirect3DDevice9_Release(device);
21704 ok(!refcount, "Device has %u references left.\n", refcount);
21705 IDirect3D9_Release(d3d9);
21706 DestroyWindow(window);
21709 static void test_line_antialiasing_blending(void)
21711 IDirect3DDevice9 *device;
21712 IDirect3D9 *d3d9;
21713 ULONG refcount;
21714 D3DCOLOR color;
21715 D3DCAPS9 caps;
21716 HWND window;
21717 HRESULT hr;
21719 static const struct
21721 struct vec3 position;
21722 DWORD diffuse;
21724 green_quad[] =
21726 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
21727 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
21728 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
21729 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
21731 static const struct
21733 struct vec3 position;
21734 DWORD diffuse;
21736 red_quad[] =
21738 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
21739 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
21740 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
21741 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
21744 window = create_window();
21745 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
21746 ok(!!d3d9, "Failed to create a D3D object.\n");
21747 if (!(device = create_device(d3d9, window, window, TRUE)))
21749 skip("Failed to create a D3D device.\n");
21750 IDirect3D9_Release(d3d9);
21751 DestroyWindow(window);
21752 return;
21755 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
21756 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
21757 trace("Line antialiasing support: %#x.\n", caps.LineCaps & D3DLINECAPS_ANTIALIAS);
21759 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
21760 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
21761 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
21762 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
21763 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
21764 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
21766 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
21767 ok(SUCCEEDED(hr), "Failed to enable blending, hr %#x.\n", hr);
21768 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_BLENDOP, D3DBLENDOP_ADD);
21769 ok(SUCCEEDED(hr), "Failed to set blend op, hr %#x.\n", hr);
21770 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
21771 ok(SUCCEEDED(hr), "Failed to set src blend, hr %#x.\n", hr);
21772 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_DESTALPHA);
21773 ok(SUCCEEDED(hr), "Failed to set dest blend, hr %#x.\n", hr);
21775 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
21776 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
21777 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
21778 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
21779 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
21780 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#x.\n", hr);
21781 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
21782 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#x.\n", hr);
21784 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
21785 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
21787 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
21788 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21789 hr = IDirect3DDevice9_BeginScene(device);
21790 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21791 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
21792 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
21793 hr = IDirect3DDevice9_EndScene(device);
21794 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
21795 color = getPixelColor(device, 320, 240);
21796 ok(color_match(color, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color);
21798 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
21799 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21800 hr = IDirect3DDevice9_BeginScene(device);
21801 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21802 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
21803 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
21804 hr = IDirect3DDevice9_EndScene(device);
21805 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
21806 color = getPixelColor(device, 320, 240);
21807 ok(color_match(color, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color);
21809 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
21810 ok(SUCCEEDED(hr), "Failed to disable blending, hr %#x.\n", hr);
21812 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
21813 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21814 hr = IDirect3DDevice9_BeginScene(device);
21815 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21816 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
21817 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
21818 hr = IDirect3DDevice9_EndScene(device);
21819 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
21820 color = getPixelColor(device, 320, 240);
21821 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
21823 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
21824 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21825 hr = IDirect3DDevice9_BeginScene(device);
21826 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21827 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
21828 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
21829 hr = IDirect3DDevice9_EndScene(device);
21830 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
21831 color = getPixelColor(device, 320, 240);
21832 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
21834 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ANTIALIASEDLINEENABLE, TRUE);
21835 ok(SUCCEEDED(hr), "Failed to enable line antialiasing, hr %#x.\n", hr);
21837 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
21838 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21839 hr = IDirect3DDevice9_BeginScene(device);
21840 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21841 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
21842 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
21843 hr = IDirect3DDevice9_EndScene(device);
21844 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
21845 color = getPixelColor(device, 320, 240);
21846 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
21848 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
21849 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21850 hr = IDirect3DDevice9_BeginScene(device);
21851 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21852 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
21853 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
21854 hr = IDirect3DDevice9_EndScene(device);
21855 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
21856 color = getPixelColor(device, 320, 240);
21857 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
21859 refcount = IDirect3DDevice9_Release(device);
21860 ok(!refcount, "Device has %u references left.\n", refcount);
21861 IDirect3D9_Release(d3d9);
21862 DestroyWindow(window);
21865 static void test_dsy(void)
21867 static const DWORD vs_code[] =
21869 0xfffe0300, /* vs_3_0 */
21870 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
21871 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
21872 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
21873 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
21874 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
21875 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
21876 0x0000ffff
21878 static const DWORD ps_code[] =
21880 0xffff0300, /* ps_3_0 */
21881 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
21882 0x05000051, 0xa00f0000, 0x43700000, 0x3f000000, 0x00000000, 0x00000000, /* def c0, 240.0, 0.5, 0.0, 0.0 */
21883 0x0200005c, 0x800f0000, 0x90e40000, /* dsy r0, v0 */
21884 0x03000005, 0x800f0000, 0x80e40000, 0xa0000000, /* mul r0, r0, c0.x */
21885 0x03000002, 0x800f0800, 0x80e40000, 0xa0550000, /* add oC0, r0, c0.y */
21886 0x0000ffff
21888 static const struct
21890 struct vec3 pos;
21891 D3DCOLOR color;
21893 quad[] =
21895 {{-1.0f, -1.0f, 0.1f}, 0x00ff0000},
21896 {{-1.0f, 1.0f, 0.1f}, 0x0000ff00},
21897 {{ 1.0f, -1.0f, 0.1f}, 0x00ff0000},
21898 {{ 1.0f, 1.0f, 0.1f}, 0x0000ff00},
21900 IDirect3DSurface9 *backbuffer, *rt;
21901 IDirect3DVertexShader9 *vs;
21902 IDirect3DPixelShader9 *ps;
21903 IDirect3DDevice9 *device;
21904 IDirect3D9 *d3d;
21905 ULONG refcount;
21906 D3DCAPS9 caps;
21907 DWORD color;
21908 HWND window;
21909 HRESULT hr;
21911 window = create_window();
21912 d3d = Direct3DCreate9(D3D_SDK_VERSION);
21913 ok(!!d3d, "Failed to create a D3D object.\n");
21914 if (!(device = create_device(d3d, window, window, TRUE)))
21916 skip("Failed to create a D3D device, skipping tests.\n");
21917 goto done;
21920 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
21921 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
21922 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
21924 skip("No ps_3_0 support, skipping dsy tests.\n");
21925 IDirect3DDevice9_Release(device);
21926 goto done;
21929 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
21930 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
21932 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
21933 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
21934 ok(SUCCEEDED(hr), "Failed to create offscreen render target, hr %#x.\n", hr);
21935 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
21936 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
21938 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
21939 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
21940 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
21941 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
21943 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
21944 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
21945 hr = IDirect3DDevice9_SetVertexShader(device, vs);
21946 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
21947 hr = IDirect3DDevice9_SetPixelShader(device, ps);
21948 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
21950 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
21951 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21952 hr = IDirect3DDevice9_BeginScene(device);
21953 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21954 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
21955 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
21956 hr = IDirect3DDevice9_EndScene(device);
21957 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
21959 color = getPixelColor(device, 360, 240);
21960 ok(color_match(color, 0x00ff007f, 1), "Got unexpected color 0x%08x.\n", color);
21962 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
21963 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
21965 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
21966 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21967 hr = IDirect3DDevice9_BeginScene(device);
21968 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21969 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
21970 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
21971 hr = IDirect3DDevice9_EndScene(device);
21972 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
21974 color = getPixelColor(device, 360, 240);
21975 ok(color_match(color, 0x00ff007f, 1), "Got unexpected color 0x%08x.\n", color);
21977 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21978 ok(SUCCEEDED(hr), "Failed to present frame, hr %#x.\n", hr);
21980 IDirect3DSurface9_Release(rt);
21981 IDirect3DSurface9_Release(backbuffer);
21982 IDirect3DVertexShader9_Release(vs);
21983 IDirect3DPixelShader9_Release(ps);
21985 refcount = IDirect3DDevice9_Release(device);
21986 ok(!refcount, "Device has %u references left.\n", refcount);
21987 done:
21988 IDirect3D9_Release(d3d);
21989 DestroyWindow(window);
21992 static void test_evict_bound_resources(void)
21994 IDirect3DVertexBuffer9 *vb;
21995 IDirect3DIndexBuffer9 *ib;
21996 IDirect3DDevice9 *device;
21997 IDirect3D9 *d3d9;
21998 ULONG refcount;
21999 D3DCOLOR color;
22000 HWND window;
22001 void *data;
22002 HRESULT hr;
22004 static const struct
22006 struct vec3 position;
22007 DWORD diffuse;
22009 green_quad[] =
22011 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
22012 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
22013 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
22014 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
22016 static const unsigned short indices[] = {0, 1, 2, 3, 2, 1};
22018 window = create_window();
22019 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
22020 ok(!!d3d9, "Failed to create a D3D object.\n");
22022 if (!(device = create_device(d3d9, window, window, TRUE)))
22024 skip("Failed to create a D3D device.\n");
22025 IDirect3D9_Release(d3d9);
22026 DestroyWindow(window);
22027 return;
22030 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0,
22031 D3DFMT_INDEX16, D3DPOOL_MANAGED, &ib, NULL);
22032 ok(SUCCEEDED(hr), "Failed to create index buffer, hr %#x.\n", hr);
22034 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(green_quad), 0,
22035 D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &vb, NULL);
22036 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
22038 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
22039 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
22040 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
22041 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
22042 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
22043 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
22045 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
22046 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
22048 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(green_quad), &data, 0);
22049 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#x.\n", hr);
22050 memcpy(data, green_quad, sizeof(green_quad));
22051 hr = IDirect3DVertexBuffer9_Unlock(vb);
22052 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#x.\n", hr);
22054 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), &data, 0);
22055 ok(hr == D3D_OK, "Failed to lock index buffer, hr %#x.\n", hr);
22056 memcpy(data, indices, sizeof(indices));
22057 hr = IDirect3DIndexBuffer9_Unlock(ib);
22058 ok(hr == D3D_OK, "Failed to unlock index buffer, hr %#x.\n", hr);
22060 hr = IDirect3DDevice9_SetIndices(device, ib);
22061 ok(hr == D3D_OK, "Failed to set index buffer, hr %#x.\n", hr);
22062 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(*green_quad));
22063 ok(hr == D3D_OK, "Failed to set stream source, hr %#x.\n", hr);
22065 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
22066 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22067 hr = IDirect3DDevice9_BeginScene(device);
22068 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22069 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
22070 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22071 hr = IDirect3DDevice9_EndScene(device);
22072 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22073 color = getPixelColor(device, 320, 240);
22074 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
22076 hr = IDirect3DDevice9_EvictManagedResources(device);
22077 ok(hr == D3D_OK, "Failed to evict managed resources, hr %#x.\n", hr);
22079 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
22080 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22081 hr = IDirect3DDevice9_BeginScene(device);
22082 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22083 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
22084 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22085 hr = IDirect3DDevice9_EndScene(device);
22086 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22087 color = getPixelColor(device, 320, 240);
22088 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
22090 IDirect3DIndexBuffer9_Release(ib);
22091 IDirect3DVertexBuffer9_Release(vb);
22092 refcount = IDirect3DDevice9_Release(device);
22093 ok(!refcount, "Device has %u references left.\n", refcount);
22094 IDirect3D9_Release(d3d9);
22095 DestroyWindow(window);
22098 /* This test shows that 0xffff is valid index in D3D9. */
22099 static void test_max_index16(void)
22101 static const struct vertex
22103 struct vec3 position;
22104 DWORD diffuse;
22106 green_quad[] =
22108 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22109 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22110 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22111 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22113 static const unsigned short indices[] = {0, 1, 2, 0xffff};
22114 static const unsigned int vertex_count = 0xffff + 1;
22116 D3DADAPTER_IDENTIFIER9 identifier;
22117 IDirect3DVertexBuffer9 *vb;
22118 IDirect3DIndexBuffer9 *ib;
22119 IDirect3DDevice9 *device;
22120 struct vertex *vb_data;
22121 IDirect3D9 *d3d9;
22122 ULONG refcount;
22123 D3DCOLOR color;
22124 D3DCAPS9 caps;
22125 HWND window;
22126 void *data;
22127 HRESULT hr;
22128 BOOL warp;
22130 window = create_window();
22131 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
22132 ok(!!d3d9, "Failed to create a D3D object.\n");
22134 hr = IDirect3D9_GetAdapterIdentifier(d3d9, D3DADAPTER_DEFAULT, 0, &identifier);
22135 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
22136 warp = adapter_is_warp(&identifier);
22138 if (!(device = create_device(d3d9, window, window, TRUE)))
22140 skip("Failed to create a D3D device.\n");
22141 IDirect3D9_Release(d3d9);
22142 DestroyWindow(window);
22143 return;
22146 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
22147 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
22148 if (caps.MaxVertexIndex < 0xffff)
22150 skip("Max vertex index is lower than 0xffff (%#x).\n", caps.MaxVertexIndex);
22151 IDirect3DDevice9_Release(device);
22152 IDirect3D9_Release(d3d9);
22153 DestroyWindow(window);
22154 return;
22157 hr = IDirect3DDevice9_CreateVertexBuffer(device, vertex_count * sizeof(*green_quad), 0,
22158 D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &vb, NULL);
22159 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
22161 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0,
22162 D3DFMT_INDEX16, D3DPOOL_MANAGED, &ib, NULL);
22163 ok(SUCCEEDED(hr), "Failed to create index buffer, hr %#x.\n", hr);
22165 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
22166 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
22167 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
22168 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
22169 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
22170 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
22172 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
22173 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
22175 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(green_quad), (void **)&vb_data, 0);
22176 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#x.\n", hr);
22177 vb_data[0] = green_quad[0];
22178 vb_data[1] = green_quad[1];
22179 vb_data[2] = green_quad[2];
22180 vb_data[0xffff] = green_quad[3];
22181 hr = IDirect3DVertexBuffer9_Unlock(vb);
22182 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#x.\n", hr);
22184 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), &data, 0);
22185 ok(hr == D3D_OK, "Failed to lock index buffer, hr %#x.\n", hr);
22186 memcpy(data, indices, sizeof(indices));
22187 hr = IDirect3DIndexBuffer9_Unlock(ib);
22188 ok(hr == D3D_OK, "Failed to unlock index buffer, hr %#x.\n", hr);
22190 hr = IDirect3DDevice9_SetIndices(device, ib);
22191 ok(hr == D3D_OK, "Failed to set index buffer, hr %#x.\n", hr);
22192 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(struct vertex));
22193 ok(hr == D3D_OK, "Failed to set stream source, hr %#x.\n", hr);
22195 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
22196 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22197 hr = IDirect3DDevice9_BeginScene(device);
22198 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22199 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 0, vertex_count, 0, 2);
22200 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22201 hr = IDirect3DDevice9_EndScene(device);
22202 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22203 color = getPixelColor(device, 20, 20);
22204 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
22205 color = getPixelColor(device, 320, 240);
22206 ok(color_match(color, 0x0000ff00, 1) || broken(warp), "Got unexpected color 0x%08x.\n", color);
22207 color = getPixelColor(device, 620, 460);
22208 ok(color_match(color, 0x0000ff00, 1) || broken(warp), "Got unexpected color 0x%08x.\n", color);
22210 IDirect3DIndexBuffer9_Release(ib);
22211 IDirect3DVertexBuffer9_Release(vb);
22212 refcount = IDirect3DDevice9_Release(device);
22213 ok(!refcount, "Device has %u references left.\n", refcount);
22214 IDirect3D9_Release(d3d9);
22215 DestroyWindow(window);
22218 static void test_backbuffer_resize(void)
22220 D3DPRESENT_PARAMETERS present_parameters = {0};
22221 IDirect3DSurface9 *backbuffer;
22222 IDirect3DDevice9 *device;
22223 IDirect3D9 *d3d;
22224 D3DCOLOR color;
22225 ULONG refcount;
22226 HWND window;
22227 HRESULT hr;
22229 static const struct
22231 struct vec3 position;
22232 DWORD diffuse;
22234 quad[] =
22236 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22237 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22238 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22239 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22242 window = create_window();
22243 d3d = Direct3DCreate9(D3D_SDK_VERSION);
22244 ok(!!d3d, "Failed to create a D3D object.\n");
22245 if (!(device = create_device(d3d, window, window, TRUE)))
22247 skip("Failed to create a D3D device.\n");
22248 goto done;
22251 /* Wine d3d9 implementation had a bug which was triggered by a
22252 * SetRenderTarget() call with an unreferenced surface. */
22253 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
22254 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
22255 refcount = IDirect3DSurface9_Release(backbuffer);
22256 ok(!refcount, "Surface has %u references left.\n", refcount);
22257 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
22258 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
22259 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
22260 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
22262 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
22263 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22264 color = getPixelColor(device, 1, 1);
22265 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
22267 present_parameters.BackBufferWidth = 800;
22268 present_parameters.BackBufferHeight = 600;
22269 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
22270 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
22271 present_parameters.hDeviceWindow = NULL;
22272 present_parameters.Windowed = TRUE;
22273 present_parameters.EnableAutoDepthStencil = TRUE;
22274 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
22275 hr = IDirect3DDevice9_Reset(device, &present_parameters);
22276 ok(SUCCEEDED(hr), "Failed to reset, hr %#x.\n", hr);
22278 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
22279 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
22280 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
22281 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
22282 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
22283 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
22284 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
22285 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
22287 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
22288 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
22289 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
22290 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
22291 IDirect3DSurface9_Release(backbuffer);
22293 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
22294 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22295 color = getPixelColor(device, 1, 1);
22296 ok(color == 0x00ffff00, "Got unexpected color 0x%08x.\n", color);
22297 color = getPixelColor(device, 700, 500);
22298 ok(color == 0x00ffff00, "Got unexpected color 0x%08x.\n", color);
22300 hr = IDirect3DDevice9_BeginScene(device);
22301 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22302 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
22303 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22304 hr = IDirect3DDevice9_EndScene(device);
22305 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22306 color = getPixelColor(device, 1, 1);
22307 ok(color == 0x0000ff00, "Got unexpected color 0x%08x.\n", color);
22308 color = getPixelColor(device, 700, 500);
22309 ok(color == 0x0000ff00, "Got unexpected color 0x%08x.\n", color);
22311 refcount = IDirect3DDevice9_Release(device);
22312 ok(!refcount, "Device has %u references left.\n", refcount);
22313 done:
22314 IDirect3D9_Release(d3d);
22315 DestroyWindow(window);
22318 static void test_drawindexedprimitiveup(void)
22320 static const struct vertex
22322 struct vec3 position;
22323 DWORD diffuse;
22325 quad[] =
22327 {{-1.0f, -1.0f, 0.1f}, 0xff00ff00},
22328 {{-1.0f, 1.0f, 0.1f}, 0xff0000ff},
22329 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
22330 {{ 1.0f, 1.0f, 0.1f}, 0xff0000ff},
22332 {{-1.0f, -1.0f, 0.1f}, 0xff0000ff},
22333 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
22334 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
22335 {{ 1.0f, 1.0f, 0.1f}, 0xff00ff00},
22337 static const unsigned short indices[] = {0, 1, 2, 3, 4, 5, 6, 7};
22338 IDirect3DDevice9 *device;
22339 IDirect3D9 *d3d;
22340 ULONG refcount;
22341 D3DCOLOR color;
22342 HWND window;
22343 HRESULT hr;
22345 window = create_window();
22346 d3d = Direct3DCreate9(D3D_SDK_VERSION);
22347 ok(!!d3d, "Failed to create a D3D object.\n");
22349 if (!(device = create_device(d3d, window, window, TRUE)))
22351 skip("Failed to create a D3D device.\n");
22352 IDirect3D9_Release(d3d);
22353 DestroyWindow(window);
22354 return;
22357 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
22358 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
22359 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
22360 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
22361 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
22362 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
22364 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
22365 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
22367 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
22368 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22370 hr = IDirect3DDevice9_BeginScene(device);
22371 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22372 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 4, 4, 2, indices + 4, D3DFMT_INDEX16, quad, sizeof(*quad));
22373 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22374 hr = IDirect3DDevice9_EndScene(device);
22375 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22377 color = getPixelColor(device, 160, 120);
22378 ok(color_match(color, 0x0040bf00, 1), "Got unexpected color 0x%08x.\n", color);
22379 color = getPixelColor(device, 480, 120);
22380 ok(color_match(color, 0x0040bf00, 1), "Got unexpected color 0x%08x.\n", color);
22381 color = getPixelColor(device, 160, 360);
22382 ok(color_match(color, 0x00404080, 1), "Got unexpected color 0x%08x.\n", color);
22383 color = getPixelColor(device, 480, 360);
22384 ok(color_match(color, 0x00bf4000, 1), "Got unexpected color 0x%08x.\n", color);
22386 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
22387 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_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 0, 4, 2, indices, D3DFMT_INDEX16, quad, sizeof(*quad));
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);
22396 color = getPixelColor(device, 160, 120);
22397 ok(color_match(color, 0x004000bf, 1), "Got unexpected color 0x%08x.\n", color);
22398 color = getPixelColor(device, 480, 120);
22399 ok(color_match(color, 0x004000bf, 1), "Got unexpected color 0x%08x.\n", color);
22400 color = getPixelColor(device, 160, 360);
22401 ok(color_match(color, 0x00408040, 1), "Got unexpected color 0x%08x.\n", color);
22402 color = getPixelColor(device, 480, 360);
22403 ok(color_match(color, 0x00bf0040, 1), "Got unexpected color 0x%08x.\n", color);
22405 refcount = IDirect3DDevice9_Release(device);
22406 ok(!refcount, "Device has %u references left.\n", refcount);
22407 IDirect3D9_Release(d3d);
22408 DestroyWindow(window);
22411 static void test_vertex_texture(void)
22413 static const D3DVERTEXELEMENT9 decl_elements[] =
22415 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
22416 D3DDECL_END()
22418 static const struct vec3 quad[] =
22420 {-1.0f, -1.0f, 0.0f},
22421 {-1.0f, 1.0f, 0.0f},
22422 { 1.0f, -1.0f, 0.0f},
22423 { 1.0f, 1.0f, 0.0f},
22425 static const DWORD vs_code[] =
22427 0xfffe0300, /* vs_3_0 */
22428 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0, 0, 0, 0 */
22429 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
22430 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
22431 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
22432 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
22433 0x0300005f, 0xe00f0001, 0xa0000000, 0xa0e40800, /* texldl o1, c0.x, s0 */
22434 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
22435 0x0000ffff, /* end */
22437 static const DWORD ps_code[] =
22439 0xffff0300, /* ps_3_0 */
22440 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color v0 */
22441 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
22442 0x0000ffff, /* end */
22444 static const DWORD texture_data[4] = {0x00ffff00, 0x00ffff00, 0x00ffff00, 0x00ffff00};
22445 IDirect3DVertexDeclaration9 *declaration;
22446 IDirect3DTexture9 *texture;
22447 IDirect3DVertexShader9 *vs;
22448 IDirect3DPixelShader9 *ps;
22449 IDirect3DDevice9 *device;
22450 D3DLOCKED_RECT lr;
22451 IDirect3D9 *d3d;
22452 D3DCOLOR color;
22453 ULONG refcount;
22454 D3DCAPS9 caps;
22455 HWND window;
22456 HRESULT hr;
22458 window = create_window();
22459 d3d = Direct3DCreate9(D3D_SDK_VERSION);
22460 ok(!!d3d, "Failed to create D3D object.\n");
22462 if (!(device = create_device(d3d, window, window, TRUE)))
22464 skip("Failed to create D3D device.\n");
22465 IDirect3D9_Release(d3d);
22466 DestroyWindow(window);
22467 return;
22470 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
22471 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
22472 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0) || caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
22474 skip("SM3 is not supported.\n");
22475 goto done;
22477 if (!(caps.VertexTextureFilterCaps & D3DPTFILTERCAPS_MAGFPOINT)
22478 || !(caps.VertexTextureFilterCaps & D3DPTFILTERCAPS_MINFPOINT))
22480 skip("Vertex texture point filtering is not supported, caps %#x.\n", caps.VertexTextureFilterCaps);
22481 goto done;
22483 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
22484 D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8);
22485 if (hr != D3D_OK)
22487 skip("No vertex texture fetch support for D3DFMT_A8R8G8B8, hr %#x.\n", hr);
22488 goto done;
22491 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
22492 ok(hr == D3D_OK, "Failed to create texture, hr %#x.\n", hr);
22493 memset(&lr, 0, sizeof(lr));
22494 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
22495 ok(hr == D3D_OK, "Failed to lock texture, hr %#x.\n", hr);
22496 memcpy(lr.pBits, texture_data, sizeof(texture_data));
22497 hr = IDirect3DTexture9_UnlockRect(texture, 0);
22498 ok(hr == D3D_OK, "Failed to unlock texture, hr %#x.\n", hr);
22500 hr = IDirect3DDevice9_SetTexture(device, D3DVERTEXTEXTURESAMPLER0, (IDirect3DBaseTexture9 *)texture);
22501 ok(hr == D3D_OK, "Failed to set texture, hr %#x.\n", hr);
22503 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &declaration);
22504 ok(SUCCEEDED(hr), "Failed to create vertex declaration, hr %#x.\n", hr);
22505 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
22506 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
22507 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
22508 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
22510 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration);
22511 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
22512 hr = IDirect3DDevice9_SetVertexShader(device, vs);
22513 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
22514 hr = IDirect3DDevice9_SetPixelShader(device, ps);
22515 ok(SUCCEEDED(hr), "Failed to set pixel shader, 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_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
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, 160, 360);
22526 ok(color == texture_data[0], "Got unexpected color 0x%08x.\n", color);
22528 IDirect3DPixelShader9_Release(ps);
22529 IDirect3DVertexShader9_Release(vs);
22530 IDirect3DTexture9_Release(texture);
22531 IDirect3DVertexDeclaration9_Release(declaration);
22532 done:
22533 refcount = IDirect3DDevice9_Release(device);
22534 ok(!refcount, "Device has %u references left.\n", refcount);
22535 IDirect3D9_Release(d3d);
22536 DestroyWindow(window);
22539 START_TEST(visual)
22541 D3DADAPTER_IDENTIFIER9 identifier;
22542 IDirect3D9 *d3d;
22543 HRESULT hr;
22545 if (!(d3d = Direct3DCreate9(D3D_SDK_VERSION)))
22547 skip("could not create D3D9 object\n");
22548 return;
22551 memset(&identifier, 0, sizeof(identifier));
22552 hr = IDirect3D9_GetAdapterIdentifier(d3d, 0, 0, &identifier);
22553 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
22554 trace("Driver string: \"%s\"\n", identifier.Driver);
22555 trace("Description string: \"%s\"\n", identifier.Description);
22556 /* Only Windows XP's default VGA driver should have an empty description */
22557 ok(identifier.Description[0] || broken(!strcmp(identifier.Driver, "vga.dll")), "Empty driver description.\n");
22558 trace("Device name string: \"%s\"\n", identifier.DeviceName);
22559 ok(identifier.DeviceName[0], "Empty device name.\n");
22560 trace("Driver version %d.%d.%d.%d\n",
22561 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
22562 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
22564 IDirect3D9_Release(d3d);
22566 test_sanity();
22567 depth_clamp_test();
22568 stretchrect_test();
22569 lighting_test();
22570 test_specular_lighting();
22571 clear_test();
22572 color_fill_test();
22573 fog_test();
22574 test_cube_wrap();
22575 z_range_test();
22576 maxmip_test();
22577 offscreen_test();
22578 ds_size_test();
22579 test_blend();
22580 test_shademode();
22581 srgbtexture_test();
22582 release_buffer_test();
22583 float_texture_test();
22584 g16r16_texture_test();
22585 pixelshader_blending_test();
22586 texture_transform_flags_test();
22587 autogen_mipmap_test();
22588 fixed_function_decl_test();
22589 conditional_np2_repeat_test();
22590 fixed_function_bumpmap_test();
22591 test_pointsize();
22592 tssargtemp_test();
22593 np2_stretch_rect_test();
22594 yuv_color_test();
22595 yuv_layout_test();
22596 zwriteenable_test();
22597 alphatest_test();
22598 viewport_test();
22599 test_constant_clamp_vs();
22600 test_compare_instructions();
22601 test_mova();
22602 loop_index_test();
22603 sincos_test();
22604 sgn_test();
22605 clip_planes_test();
22606 test_vshader_input();
22607 test_vshader_float16();
22608 stream_test();
22609 fog_with_shader_test();
22610 texbem_test();
22611 texdepth_test();
22612 texkill_test();
22613 volume_v16u16_test();
22614 constant_clamp_ps_test();
22615 cnd_test();
22616 dp2add_ps_test();
22617 unbound_sampler_test();
22618 nested_loop_test();
22619 pretransformed_varying_test();
22620 vface_register_test();
22621 test_fragment_coords();
22622 multiple_rendertargets_test();
22623 texop_test();
22624 texop_range_test();
22625 alphareplicate_test();
22626 dp3_alpha_test();
22627 depth_buffer_test();
22628 depth_buffer2_test();
22629 depth_blit_test();
22630 intz_test();
22631 shadow_test();
22632 fp_special_test();
22633 depth_bounds_test();
22634 srgbwrite_format_test();
22635 update_surface_test();
22636 multisample_get_rtdata_test();
22637 zenable_test();
22638 fog_special_test();
22639 volume_srgb_test();
22640 volume_dxt5_test();
22641 add_dirty_rect_test();
22642 multisampled_depth_buffer_test();
22643 resz_test();
22644 stencil_cull_test();
22645 test_per_stage_constant();
22646 test_3dc_formats();
22647 test_fog_interpolation();
22648 test_negative_fixedfunction_fog();
22649 test_position_index();
22650 test_table_fog_zw();
22651 test_signed_formats();
22652 test_multisample_mismatch();
22653 test_texcoordindex();
22654 test_vertex_blending();
22655 test_updatetexture();
22656 test_depthbias();
22657 test_flip();
22658 test_uninitialized_varyings();
22659 test_multisample_init();
22660 test_texture_blending();
22661 test_color_clamping();
22662 test_line_antialiasing_blending();
22663 test_dsy();
22664 test_evict_bound_resources();
22665 test_max_index16();
22666 test_backbuffer_resize();
22667 test_drawindexedprimitiveup();
22668 test_vertex_texture();