d3d9/tests: Extend autogen_mipmap_test().
[wine.git] / dlls / d3d9 / tests / visual.c
blobc745c1b92400974e0b38e5ae322aae0f5b480d08
1 /*
2 * Copyright 2005, 2007-2008 Henri Verbeet
3 * Copyright (C) 2007-2013 Stefan Dösinger(for CodeWeavers)
4 * Copyright (C) 2008 Jason Green(for TransGaming)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 /* This test framework allows limited testing of rendering results. Things are rendered, shown on
22 * the framebuffer, read back from there and compared to expected colors.
24 * However, neither d3d nor opengl is guaranteed to be pixel exact, and thus the capability of this test
25 * is rather limited. As a general guideline for adding tests, do not rely on corner pixels. Draw a big enough
26 * area which shows specific behavior(like a quad on the whole screen), and try to get resulting colors with
27 * all bits set or unset in all channels(like pure red, green, blue, white, black). Hopefully everything that
28 * causes visible results in games can be tested in a way that does not depend on pixel exactness
31 #include <math.h>
33 #define COBJMACROS
34 #include <d3d9.h>
35 #include "wine/test.h"
37 struct vec2
39 float x, y;
42 struct vec3
44 float x, y, z;
47 struct vec4
49 float x, y, z, w;
52 static HWND create_window(void)
54 HWND hwnd;
55 RECT rect;
57 SetRect(&rect, 0, 0, 640, 480);
58 AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE);
59 hwnd = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
60 0, 0, rect.right - rect.left, rect.bottom - rect.top, 0, 0, 0, 0);
61 return hwnd;
64 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
66 if (abs((int)(c1 & 0xff) - (int)(c2 & 0xff)) > max_diff) return FALSE;
67 c1 >>= 8; c2 >>= 8;
68 if (abs((int)(c1 & 0xff) - (int)(c2 & 0xff)) > max_diff) return FALSE;
69 c1 >>= 8; c2 >>= 8;
70 if (abs((int)(c1 & 0xff) - (int)(c2 & 0xff)) > max_diff) return FALSE;
71 c1 >>= 8; c2 >>= 8;
72 if (abs((int)(c1 & 0xff) - (int)(c2 & 0xff)) > max_diff) return FALSE;
73 return TRUE;
76 static BOOL adapter_is_warp(const D3DADAPTER_IDENTIFIER9 *identifier)
78 return !strcmp(identifier->Driver, "d3d10warp.dll");
81 /* Locks a given surface and returns the color at (x,y). It's the caller's
82 * responsibility to only pass in lockable surfaces and valid x,y coordinates */
83 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
85 DWORD color;
86 HRESULT hr;
87 D3DSURFACE_DESC desc;
88 RECT rectToLock = {x, y, x+1, y+1};
89 D3DLOCKED_RECT lockedRect;
91 hr = IDirect3DSurface9_GetDesc(surface, &desc);
92 if(FAILED(hr)) /* This is not a test */
94 trace("Can't get the surface description, hr=%08x\n", hr);
95 return 0xdeadbeef;
98 hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
99 if(FAILED(hr)) /* This is not a test */
101 trace("Can't lock the surface, hr=%08x\n", hr);
102 return 0xdeadbeef;
104 switch(desc.Format) {
105 case D3DFMT_A8R8G8B8:
107 color = ((DWORD *) lockedRect.pBits)[0];
108 break;
110 default:
111 trace("Error: unknown surface format: %d\n", desc.Format);
112 color = 0xdeadbeef;
113 break;
115 hr = IDirect3DSurface9_UnlockRect(surface);
116 if(FAILED(hr))
118 trace("Can't unlock the surface, hr=%08x\n", hr);
120 return color;
123 struct surface_readback
125 IDirect3DSurface9 *surface;
126 D3DLOCKED_RECT locked_rect;
129 static void get_rt_readback(IDirect3DSurface9 *surface, struct surface_readback *rb)
131 IDirect3DDevice9 *device;
132 D3DSURFACE_DESC desc;
133 HRESULT hr;
135 memset(rb, 0, sizeof(*rb));
136 hr = IDirect3DSurface9_GetDevice(surface, &device);
137 ok(SUCCEEDED(hr), "Failed to get device, hr %#x.\n", hr);
138 hr = IDirect3DSurface9_GetDesc(surface, &desc);
139 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
140 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, desc.Width, desc.Height,
141 desc.Format, D3DPOOL_SYSTEMMEM, &rb->surface, NULL);
142 if (FAILED(hr) || !rb->surface)
144 trace("Can't create an offscreen plain surface to read the render target data, hr %#x.\n", hr);
145 goto error;
148 hr = IDirect3DDevice9_GetRenderTargetData(device, surface, rb->surface);
149 if (FAILED(hr))
151 trace("Can't read the render target data, hr %#x.\n", hr);
152 goto error;
155 hr = IDirect3DSurface9_LockRect(rb->surface, &rb->locked_rect, NULL, D3DLOCK_READONLY);
156 if (FAILED(hr))
158 trace("Can't lock the offscreen surface, hr %#x.\n", hr);
159 goto error;
161 IDirect3DDevice9_Release(device);
163 return;
165 error:
166 if (rb->surface)
167 IDirect3DSurface9_Release(rb->surface);
168 rb->surface = NULL;
169 IDirect3DDevice9_Release(device);
172 static DWORD get_readback_color(struct surface_readback *rb, unsigned int x, unsigned int y)
174 return rb->locked_rect.pBits
175 ? ((DWORD *)rb->locked_rect.pBits)[y * rb->locked_rect.Pitch / sizeof(DWORD) + x] : 0xdeadbeef;
178 static void release_surface_readback(struct surface_readback *rb)
180 HRESULT hr;
182 if (!rb->surface)
183 return;
184 if (rb->locked_rect.pBits && FAILED(hr = IDirect3DSurface9_UnlockRect(rb->surface)))
185 trace("Can't unlock the offscreen surface, hr %#x.\n", hr);
186 IDirect3DSurface9_Release(rb->surface);
189 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
191 DWORD ret;
192 IDirect3DSurface9 *rt;
193 struct surface_readback rb;
194 HRESULT hr;
196 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
197 if(FAILED(hr))
199 trace("Can't get the render target, hr %#x.\n", hr);
200 return 0xdeadbeed;
203 get_rt_readback(rt, &rb);
204 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
205 * really important for these tests
207 ret = get_readback_color(&rb, x, y) & 0x00ffffff;
208 release_surface_readback(&rb);
210 IDirect3DSurface9_Release(rt);
211 return ret;
214 static IDirect3DDevice9 *create_device(IDirect3D9 *d3d, HWND device_window, HWND focus_window, BOOL windowed)
216 D3DPRESENT_PARAMETERS present_parameters = {0};
217 IDirect3DDevice9 *device;
219 present_parameters.Windowed = windowed;
220 present_parameters.hDeviceWindow = device_window;
221 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
222 present_parameters.BackBufferWidth = 640;
223 present_parameters.BackBufferHeight = 480;
224 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
225 present_parameters.EnableAutoDepthStencil = TRUE;
226 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
228 if (SUCCEEDED(IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
229 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device)))
230 return device;
232 return NULL;
235 static void cleanup_device(IDirect3DDevice9 *device)
237 if (device)
239 D3DPRESENT_PARAMETERS present_parameters;
240 IDirect3DSwapChain9 *swapchain;
241 ULONG ref;
243 IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
244 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
245 IDirect3DSwapChain9_Release(swapchain);
246 ref = IDirect3DDevice9_Release(device);
247 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
248 DestroyWindow(present_parameters.hDeviceWindow);
252 static void test_sanity(void)
254 IDirect3DDevice9 *device;
255 IDirect3D9 *d3d;
256 D3DCOLOR color;
257 ULONG refcount;
258 HWND window;
259 HRESULT hr;
261 window = create_window();
262 d3d = Direct3DCreate9(D3D_SDK_VERSION);
263 ok(!!d3d, "Failed to create a D3D object.\n");
264 if (!(device = create_device(d3d, window, window, TRUE)))
266 skip("Failed to create a D3D device, skipping tests.\n");
267 goto done;
270 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
271 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
272 color = getPixelColor(device, 1, 1);
273 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
275 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
276 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
278 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
279 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
280 color = getPixelColor(device, 639, 479);
281 ok(color == 0x0000ddee, "Got unexpected color 0x%08x.\n", color);
283 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
284 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
286 refcount = IDirect3DDevice9_Release(device);
287 ok(!refcount, "Device has %u references left.\n", refcount);
288 done:
289 IDirect3D9_Release(d3d);
290 DestroyWindow(window);
293 static void lighting_test(void)
295 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
296 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
297 IDirect3DDevice9 *device;
298 D3DMATERIAL9 material;
299 IDirect3D9 *d3d;
300 D3DCOLOR color;
301 ULONG refcount;
302 HWND window;
303 HRESULT hr;
304 unsigned int i;
306 static const D3DMATRIX mat =
308 1.0f, 0.0f, 0.0f, 0.0f,
309 0.0f, 1.0f, 0.0f, 0.0f,
310 0.0f, 0.0f, 1.0f, 0.0f,
311 0.0f, 0.0f, 0.0f, 1.0f,
312 }}},
313 mat_singular =
315 1.0f, 0.0f, 1.0f, 0.0f,
316 0.0f, 1.0f, 0.0f, 0.0f,
317 1.0f, 0.0f, 1.0f, 0.0f,
318 0.0f, 0.0f, 0.5f, 1.0f,
319 }}},
320 mat_transf =
322 0.0f, 0.0f, 1.0f, 0.0f,
323 0.0f, 1.0f, 0.0f, 0.0f,
324 -1.0f, 0.0f, 0.0f, 0.0f,
325 10.f, 10.0f, 10.0f, 1.0f,
326 }}},
327 mat_nonaffine =
329 1.0f, 0.0f, 0.0f, 0.0f,
330 0.0f, 1.0f, 0.0f, 0.0f,
331 0.0f, 0.0f, 1.0f, -1.0f,
332 10.f, 10.0f, 10.0f, 0.0f,
333 }}};
334 static const struct
336 struct vec3 position;
337 DWORD diffuse;
339 unlitquad[] =
341 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
342 {{-1.0f, 0.0f, 0.1f}, 0xffff0000},
343 {{ 0.0f, 0.0f, 0.1f}, 0xffff0000},
344 {{ 0.0f, -1.0f, 0.1f}, 0xffff0000},
346 litquad[] =
348 {{-1.0f, 0.0f, 0.1f}, 0xff00ff00},
349 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
350 {{ 0.0f, 1.0f, 0.1f}, 0xff00ff00},
351 {{ 0.0f, 0.0f, 0.1f}, 0xff00ff00},
353 lighting_test[] =
355 {{-1.0f, -1.0f, 0.1f}, 0x8000ff00},
356 {{ 1.0f, -1.0f, 0.1f}, 0x80000000},
357 {{-1.0f, 1.0f, 0.1f}, 0x8000ff00},
358 {{ 1.0f, 1.0f, 0.1f}, 0x80000000},
360 static const struct
362 struct vec3 position;
363 struct vec3 normal;
364 DWORD diffuse;
366 unlitnquad[] =
368 {{0.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
369 {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
370 {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
371 {{1.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
373 litnquad[] =
375 {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
376 {{0.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
377 {{1.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
378 {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
380 nquad[] =
382 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
383 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
384 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
385 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
387 rotatedquad[] =
389 {{-10.0f, -11.0f, 11.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
390 {{-10.0f, -9.0f, 11.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
391 {{-10.0f, -9.0f, 9.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
392 {{-10.0f, -11.0f, 9.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
394 translatedquad[] =
396 {{-11.0f, -11.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
397 {{-11.0f, -9.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
398 {{ -9.0f, -9.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
399 {{ -9.0f, -11.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
401 static const WORD indices[] = {0, 1, 2, 2, 3, 0};
402 static const struct
404 const D3DMATRIX *world_matrix;
405 const void *quad;
406 unsigned int size;
407 DWORD expected;
408 const char *message;
410 tests[] =
412 {&mat, nquad, sizeof(nquad[0]), 0x000000ff, "Lit quad with light"},
413 {&mat_singular, nquad, sizeof(nquad[0]), 0x000000ff, "Lit quad with singular world matrix"},
414 {&mat_transf, rotatedquad, sizeof(rotatedquad[0]), 0x000000ff, "Lit quad with transformation matrix"},
415 {&mat_nonaffine, translatedquad, sizeof(translatedquad[0]), 0x00000000, "Lit quad with non-affine matrix"},
418 window = create_window();
419 d3d = Direct3DCreate9(D3D_SDK_VERSION);
420 ok(!!d3d, "Failed to create a D3D object.\n");
421 if (!(device = create_device(d3d, window, window, TRUE)))
423 skip("Failed to create a D3D device, skipping tests.\n");
424 goto done;
427 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
428 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
430 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &mat);
431 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
432 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
433 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
434 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
435 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
436 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
437 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
438 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
439 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
440 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
441 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
442 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
443 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
444 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
445 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
447 hr = IDirect3DDevice9_SetFVF(device, fvf);
448 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
450 hr = IDirect3DDevice9_BeginScene(device);
451 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
453 /* No lights are defined... That means, lit vertices should be entirely black */
454 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
455 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
456 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
457 2, indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
458 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
460 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
461 ok(SUCCEEDED(hr), "Failed to enable lighting, hr %#x.\n", hr);
462 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
463 2, indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
464 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
466 hr = IDirect3DDevice9_SetFVF(device, nfvf);
467 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
469 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
470 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
471 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
472 2, indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
473 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
475 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
476 ok(SUCCEEDED(hr), "Failed to enable lighting, hr %#x.\n", hr);
477 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
478 2, indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
479 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
481 hr = IDirect3DDevice9_EndScene(device);
482 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
484 color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
485 ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
486 color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
487 ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
488 color = getPixelColor(device, 480, 360); /* Lower left quad - unlit with normals */
489 ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
490 color = getPixelColor(device, 480, 120); /* Upper left quad - lit with normals */
491 ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
493 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
495 hr = IDirect3DDevice9_LightEnable(device, 0, TRUE);
496 ok(SUCCEEDED(hr), "Failed to enable light 0, hr %#x.\n", hr);
498 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
500 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, tests[i].world_matrix);
501 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
503 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
504 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
506 hr = IDirect3DDevice9_BeginScene(device);
507 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
509 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
510 2, indices, D3DFMT_INDEX16, tests[i].quad, tests[i].size);
511 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
513 hr = IDirect3DDevice9_EndScene(device);
514 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
516 color = getPixelColor(device, 320, 240);
517 ok(color == tests[i].expected, "%s has color 0x%08x.\n", tests[i].message, color);
520 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
521 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
522 hr = IDirect3DDevice9_LightEnable(device, 0, FALSE);
523 ok(SUCCEEDED(hr), "Failed to disable light 0, hr %#x.\n", hr);
525 memset(&material, 0, sizeof(material));
526 material.Diffuse.r = 0.0;
527 material.Diffuse.g = 0.0;
528 material.Diffuse.b = 0.0;
529 material.Diffuse.a = 1.0;
530 material.Ambient.r = 0.0;
531 material.Ambient.g = 0.0;
532 material.Ambient.b = 0.0;
533 material.Ambient.a = 0.0;
534 material.Specular.r = 0.0;
535 material.Specular.g = 0.0;
536 material.Specular.b = 0.0;
537 material.Specular.a = 0.0;
538 material.Emissive.r = 0.0;
539 material.Emissive.g = 0.0;
540 material.Emissive.b = 0.0;
541 material.Emissive.a = 0.0;
542 material.Power = 0.0;
543 hr = IDirect3DDevice9_SetMaterial(device, &material);
544 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
546 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
547 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
548 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
549 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
551 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
552 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
553 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
554 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
556 hr = IDirect3DDevice9_BeginScene(device);
557 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
559 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
560 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
561 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
562 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
564 hr = IDirect3DDevice9_EndScene(device);
565 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
567 color = getPixelColor(device, 320, 240);
568 ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
569 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
571 refcount = IDirect3DDevice9_Release(device);
572 ok(!refcount, "Device has %u references left.\n", refcount);
573 done:
574 IDirect3D9_Release(d3d);
575 DestroyWindow(window);
578 static void test_specular_lighting(void)
580 static const unsigned int vertices_side = 5;
581 const unsigned int indices_count = (vertices_side - 1) * (vertices_side - 1) * 2 * 3;
582 static const DWORD fvf = D3DFVF_XYZ | D3DFVF_NORMAL;
583 static const D3DMATRIX mat =
585 1.0f, 0.0f, 0.0f, 0.0f,
586 0.0f, 1.0f, 0.0f, 0.0f,
587 0.0f, 0.0f, 1.0f, 0.0f,
588 0.0f, 0.0f, 0.0f, 1.0f,
589 }}};
590 static const D3DLIGHT9 directional =
592 D3DLIGHT_DIRECTIONAL,
593 {0.0f, 0.0f, 0.0f, 0.0f},
594 {1.0f, 1.0f, 1.0f, 0.0f},
595 {0.0f, 0.0f, 0.0f, 0.0f},
596 {0.0f, 0.0f, 0.0f},
597 {0.0f, 0.0f, 1.0f},
599 point =
601 D3DLIGHT_POINT,
602 {0.0f, 0.0f, 0.0f, 0.0f},
603 {1.0f, 1.0f, 1.0f, 0.0f},
604 {0.0f, 0.0f, 0.0f, 0.0f},
605 {0.0f, 0.0f, 0.0f},
606 {0.0f, 0.0f, 0.0f},
607 100.0f,
608 0.0f,
609 0.0f, 0.0f, 1.0f,
611 spot =
613 D3DLIGHT_SPOT,
614 {0.0f, 0.0f, 0.0f, 0.0f},
615 {1.0f, 1.0f, 1.0f, 0.0f},
616 {0.0f, 0.0f, 0.0f, 0.0f},
617 {0.0f, 0.0f, 0.0f},
618 {0.0f, 0.0f, 1.0f},
619 100.0f,
620 1.0f,
621 0.0f, 0.0f, 1.0f,
622 M_PI / 12.0f, M_PI / 3.0f
624 /* The chosen range value makes the test fail when using a manhattan
625 * distance metric vs the correct euclidean distance. */
626 point_range =
628 D3DLIGHT_POINT,
629 {0.0f, 0.0f, 0.0f, 0.0f},
630 {1.0f, 1.0f, 1.0f, 0.0f},
631 {0.0f, 0.0f, 0.0f, 0.0f},
632 {0.0f, 0.0f, 0.0f},
633 {0.0f, 0.0f, 0.0f},
634 1.2f,
635 0.0f,
636 0.0f, 0.0f, 1.0f,
638 point_side =
640 D3DLIGHT_POINT,
641 {0.0f, 0.0f, 0.0f, 0.0f},
642 {1.0f, 1.0f, 1.0f, 0.0f},
643 {0.0f, 0.0f, 0.0f, 0.0f},
644 {-1.1f, 0.0f, 1.1f},
645 {0.0f, 0.0f, 0.0f},
646 100.0f,
647 0.0f,
648 0.0f, 0.0f, 1.0f,
650 static const struct expected_color
652 unsigned int x, y;
653 D3DCOLOR color;
655 expected_directional[] =
657 {160, 120, 0x00ffffff},
658 {320, 120, 0x00ffffff},
659 {480, 120, 0x00ffffff},
660 {160, 240, 0x00ffffff},
661 {320, 240, 0x00ffffff},
662 {480, 240, 0x00ffffff},
663 {160, 360, 0x00ffffff},
664 {320, 360, 0x00ffffff},
665 {480, 360, 0x00ffffff},
667 expected_directional_local[] =
669 {160, 120, 0x003c3c3c},
670 {320, 120, 0x00717171},
671 {480, 120, 0x003c3c3c},
672 {160, 240, 0x00717171},
673 {320, 240, 0x00ffffff},
674 {480, 240, 0x00717171},
675 {160, 360, 0x003c3c3c},
676 {320, 360, 0x00717171},
677 {480, 360, 0x003c3c3c},
679 expected_point[] =
681 {160, 120, 0x00282828},
682 {320, 120, 0x005a5a5a},
683 {480, 120, 0x00282828},
684 {160, 240, 0x005a5a5a},
685 {320, 240, 0x00ffffff},
686 {480, 240, 0x005a5a5a},
687 {160, 360, 0x00282828},
688 {320, 360, 0x005a5a5a},
689 {480, 360, 0x00282828},
691 expected_point_local[] =
693 {160, 120, 0x00000000},
694 {320, 120, 0x00070707},
695 {480, 120, 0x00000000},
696 {160, 240, 0x00070707},
697 {320, 240, 0x00ffffff},
698 {480, 240, 0x00070707},
699 {160, 360, 0x00000000},
700 {320, 360, 0x00070707},
701 {480, 360, 0x00000000},
703 expected_spot[] =
705 {160, 120, 0x00000000},
706 {320, 120, 0x00141414},
707 {480, 120, 0x00000000},
708 {160, 240, 0x00141414},
709 {320, 240, 0x00ffffff},
710 {480, 240, 0x00141414},
711 {160, 360, 0x00000000},
712 {320, 360, 0x00141414},
713 {480, 360, 0x00000000},
715 expected_spot_local[] =
717 {160, 120, 0x00000000},
718 {320, 120, 0x00020202},
719 {480, 120, 0x00000000},
720 {160, 240, 0x00020202},
721 {320, 240, 0x00ffffff},
722 {480, 240, 0x00020202},
723 {160, 360, 0x00000000},
724 {320, 360, 0x00020202},
725 {480, 360, 0x00000000},
727 expected_point_range[] =
729 {160, 120, 0x00000000},
730 {320, 120, 0x005a5a5a},
731 {480, 120, 0x00000000},
732 {160, 240, 0x005a5a5a},
733 {320, 240, 0x00ffffff},
734 {480, 240, 0x005a5a5a},
735 {160, 360, 0x00000000},
736 {320, 360, 0x005a5a5a},
737 {480, 360, 0x00000000},
739 expected_point_side[] =
741 {160, 120, 0x00000000},
742 {320, 120, 0x00000000},
743 {480, 120, 0x00000000},
744 {160, 240, 0x00000000},
745 {320, 240, 0x00000000},
746 {480, 240, 0x00000000},
747 {160, 360, 0x00000000},
748 {320, 360, 0x00000000},
749 {480, 360, 0x00000000},
751 static const struct
753 const D3DLIGHT9 *light;
754 BOOL local_viewer;
755 float specular_power;
756 const struct expected_color *expected;
757 unsigned int expected_count;
759 tests[] =
761 {&directional, FALSE, 30.0f, expected_directional,
762 sizeof(expected_directional) / sizeof(expected_directional[0])},
763 {&directional, TRUE, 30.0f, expected_directional_local,
764 sizeof(expected_directional_local) / sizeof(expected_directional_local[0])},
765 {&point, FALSE, 30.0f, expected_point,
766 sizeof(expected_point) / sizeof(expected_point[0])},
767 {&point, TRUE, 30.0f, expected_point_local,
768 sizeof(expected_point_local) / sizeof(expected_point_local[0])},
769 {&spot, FALSE, 30.0f, expected_spot,
770 sizeof(expected_spot) / sizeof(expected_spot[0])},
771 {&spot, TRUE, 30.0f, expected_spot_local,
772 sizeof(expected_spot_local) / sizeof(expected_spot_local[0])},
773 {&point_range, FALSE, 30.0f, expected_point_range,
774 sizeof(expected_point_range) / sizeof(expected_point_range[0])},
775 {&point_side, TRUE, 0.0f, expected_point_side,
776 sizeof(expected_point_side) / sizeof(expected_point_side[0])},
778 IDirect3DDevice9 *device;
779 D3DMATERIAL9 material;
780 IDirect3D9 *d3d;
781 D3DCOLOR color;
782 ULONG refcount;
783 HWND window;
784 HRESULT hr;
785 unsigned int i, j, x, y;
786 struct
788 struct vec3 position;
789 struct vec3 normal;
790 } *quad;
791 WORD *indices;
793 quad = HeapAlloc(GetProcessHeap(), 0, vertices_side * vertices_side * sizeof(*quad));
794 indices = HeapAlloc(GetProcessHeap(), 0, indices_count * sizeof(*indices));
795 for (i = 0, y = 0; y < vertices_side; ++y)
797 for (x = 0; x < vertices_side; ++x)
799 quad[i].position.x = x * 2.0f / (vertices_side - 1) - 1.0f;
800 quad[i].position.y = y * 2.0f / (vertices_side - 1) - 1.0f;
801 quad[i].position.z = 1.0f;
802 quad[i].normal.x = 0.0f;
803 quad[i].normal.y = 0.0f;
804 quad[i++].normal.z = -1.0f;
807 for (i = 0, y = 0; y < (vertices_side - 1); ++y)
809 for (x = 0; x < (vertices_side - 1); ++x)
811 indices[i++] = y * vertices_side + x + 1;
812 indices[i++] = y * vertices_side + x;
813 indices[i++] = (y + 1) * vertices_side + x;
814 indices[i++] = y * vertices_side + x + 1;
815 indices[i++] = (y + 1) * vertices_side + x;
816 indices[i++] = (y + 1) * vertices_side + x + 1;
820 window = create_window();
821 d3d = Direct3DCreate9(D3D_SDK_VERSION);
822 ok(!!d3d, "Failed to create a D3D object.\n");
823 if (!(device = create_device(d3d, window, window, TRUE)))
825 skip("Failed to create a D3D device, skipping tests.\n");
826 goto done;
829 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
830 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
831 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
832 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
833 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
834 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
835 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
836 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
837 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
838 ok(SUCCEEDED(hr), "Failed to disable z test, hr %#x.\n", hr);
839 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
840 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
842 hr = IDirect3DDevice9_SetFVF(device, fvf);
843 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
845 hr = IDirect3DDevice9_LightEnable(device, 0, TRUE);
846 ok(SUCCEEDED(hr), "Failed to enable light 0, hr %#x.\n", hr);
847 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
848 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#x.\n", hr);
850 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
852 hr = IDirect3DDevice9_SetLight(device, 0, tests[i].light);
853 ok(SUCCEEDED(hr), "Failed to set light parameters, hr %#x.\n", hr);
855 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LOCALVIEWER, tests[i].local_viewer);
856 ok(SUCCEEDED(hr), "Failed to set local viewer state, hr %#x.\n", hr);
858 memset(&material, 0, sizeof(material));
859 material.Specular.r = 1.0f;
860 material.Specular.g = 1.0f;
861 material.Specular.b = 1.0f;
862 material.Specular.a = 1.0f;
863 material.Power = tests[i].specular_power;
864 hr = IDirect3DDevice9_SetMaterial(device, &material);
865 ok(SUCCEEDED(hr), "Failed to set material, hr %#x.\n", hr);
867 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
868 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
870 hr = IDirect3DDevice9_BeginScene(device);
871 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
873 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST,
874 0, vertices_side * vertices_side, indices_count / 3, indices,
875 D3DFMT_INDEX16, quad, sizeof(quad[0]));
876 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
878 hr = IDirect3DDevice9_EndScene(device);
879 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
881 for (j = 0; j < tests[i].expected_count; ++j)
883 color = getPixelColor(device, tests[i].expected[j].x, tests[i].expected[j].y);
884 ok(color_match(color, tests[i].expected[j].color, 1),
885 "Expected color 0x%08x at location (%u, %u), got 0x%08x, case %u.\n",
886 tests[i].expected[j].color, tests[i].expected[j].x,
887 tests[i].expected[j].y, color, i);
891 refcount = IDirect3DDevice9_Release(device);
892 ok(!refcount, "Device has %u references left.\n", refcount);
893 done:
894 IDirect3D9_Release(d3d);
895 DestroyWindow(window);
896 HeapFree(GetProcessHeap(), 0, indices);
897 HeapFree(GetProcessHeap(), 0, quad);
900 static void clear_test(void)
902 static const D3DMATRIX mat =
904 1.0f, 0.0f, 0.0f, 0.0f,
905 0.0f, 1.0f, 0.0f, 0.0f,
906 0.0f, 0.0f, 1.0f, 0.0f,
907 0.0f, 0.0f, 0.0f, 1.0f,
908 }}};
909 static const struct
911 struct vec3 position;
912 DWORD diffuse;
914 quad[] =
916 {{-1.0f, -1.0f, 0.1f}, 0xff7f7f7f},
917 {{ 1.0f, -1.0f, 0.1f}, 0xff7f7f7f},
918 {{-1.0f, 1.0f, 0.1f}, 0xff7f7f7f},
919 {{ 1.0f, 1.0f, 0.1f}, 0xff7f7f7f},
921 IDirect3DSurface9 *surface0, *surface1, *backbuffer;
922 IDirect3DTexture9 *texture;
923 HRESULT hr;
924 D3DRECT rect[2];
925 D3DRECT rect_negneg;
926 DWORD color;
927 D3DVIEWPORT9 old_vp, vp;
928 RECT scissor;
929 DWORD oldColorWrite;
930 BOOL invalid_clear_failed = FALSE, srgb_supported;
931 IDirect3DDevice9 *device;
932 IDirect3D9 *d3d;
933 ULONG refcount;
934 HWND window;
936 window = create_window();
937 d3d = Direct3DCreate9(D3D_SDK_VERSION);
938 ok(!!d3d, "Failed to create a D3D object.\n");
939 if (!(device = create_device(d3d, window, window, TRUE)))
941 skip("Failed to create a D3D device, skipping tests.\n");
942 goto done;
945 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
946 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
948 /* Positive x, negative y */
949 rect[0].x1 = 0;
950 rect[0].y1 = 480;
951 rect[0].x2 = 320;
952 rect[0].y2 = 240;
954 /* Positive x, positive y */
955 rect[1].x1 = 0;
956 rect[1].y1 = 0;
957 rect[1].x2 = 320;
958 rect[1].y2 = 240;
959 /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
960 * returns D3D_OK, but ignores the rectangle silently
962 hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
963 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
964 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
966 /* negative x, negative y */
967 rect_negneg.x1 = 640;
968 rect_negneg.y1 = 240;
969 rect_negneg.x2 = 320;
970 rect_negneg.y2 = 0;
971 hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
972 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
973 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
975 color = getPixelColor(device, 160, 360); /* lower left quad */
976 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
977 color = getPixelColor(device, 160, 120); /* upper left quad */
978 if(invalid_clear_failed) {
979 /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
980 ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
981 } else {
982 /* If the negative rectangle was dropped silently, the correct ones are cleared */
983 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
985 color = getPixelColor(device, 480, 360); /* lower right quad */
986 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
987 color = getPixelColor(device, 480, 120); /* upper right quad */
988 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
990 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
992 /* Hack to work around a nvidia windows driver bug. The clear below is supposed to
993 * clear the red quad in the top left part of the render target. For some reason it
994 * doesn't work if the clear color is 0xffffffff on some versions of the Nvidia Windows
995 * driver(tested on 8.17.12.5896, Win7). A clear with a different color works around
996 * this bug and fixes the clear with the white color. Even 0xfeffffff works, but let's
997 * pick some obvious value
999 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbabe, 0.0, 0);
1000 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1002 /* Test how the viewport affects clears */
1003 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1004 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1005 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
1006 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
1008 vp.X = 160;
1009 vp.Y = 120;
1010 vp.Width = 160;
1011 vp.Height = 120;
1012 vp.MinZ = 0.0;
1013 vp.MaxZ = 1.0;
1014 hr = IDirect3DDevice9_SetViewport(device, &vp);
1015 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
1016 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1017 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1019 vp.X = 320;
1020 vp.Y = 240;
1021 vp.Width = 320;
1022 vp.Height = 240;
1023 vp.MinZ = 0.0;
1024 vp.MaxZ = 1.0;
1025 hr = IDirect3DDevice9_SetViewport(device, &vp);
1026 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
1027 rect[0].x1 = 160;
1028 rect[0].y1 = 120;
1029 rect[0].x2 = 480;
1030 rect[0].y2 = 360;
1031 hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1032 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1034 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
1035 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
1037 color = getPixelColor(device, 158, 118);
1038 ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
1039 color = getPixelColor(device, 162, 118);
1040 ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
1041 color = getPixelColor(device, 158, 122);
1042 ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
1043 color = getPixelColor(device, 162, 122);
1044 ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
1046 color = getPixelColor(device, 318, 238);
1047 ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
1048 color = getPixelColor(device, 322, 238);
1049 ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
1050 color = getPixelColor(device, 318, 242);
1051 ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
1052 color = getPixelColor(device, 322, 242);
1053 ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
1055 color = getPixelColor(device, 478, 358);
1056 ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
1057 color = getPixelColor(device, 482, 358);
1058 ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
1059 color = getPixelColor(device, 478, 362);
1060 ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
1061 color = getPixelColor(device, 482, 362);
1062 ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
1064 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1066 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1067 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1069 SetRect(&scissor, 160, 120, 480, 360);
1070 hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
1071 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
1072 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
1073 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
1075 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1076 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1077 hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1078 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1080 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
1081 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
1083 color = getPixelColor(device, 158, 118);
1084 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
1085 color = getPixelColor(device, 162, 118);
1086 ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
1087 color = getPixelColor(device, 158, 122);
1088 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
1089 color = getPixelColor(device, 162, 122);
1090 ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
1092 color = getPixelColor(device, 158, 358);
1093 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
1094 color = getPixelColor(device, 162, 358);
1095 ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
1096 color = getPixelColor(device, 158, 358);
1097 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
1098 color = getPixelColor(device, 162, 362);
1099 ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
1101 color = getPixelColor(device, 478, 118);
1102 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
1103 color = getPixelColor(device, 478, 122);
1104 ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
1105 color = getPixelColor(device, 482, 122);
1106 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
1107 color = getPixelColor(device, 482, 358);
1108 ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
1110 color = getPixelColor(device, 478, 358);
1111 ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
1112 color = getPixelColor(device, 478, 362);
1113 ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
1114 color = getPixelColor(device, 482, 358);
1115 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
1116 color = getPixelColor(device, 482, 362);
1117 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
1119 color = getPixelColor(device, 318, 238);
1120 ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
1121 color = getPixelColor(device, 318, 242);
1122 ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
1123 color = getPixelColor(device, 322, 238);
1124 ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
1125 color = getPixelColor(device, 322, 242);
1126 ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
1128 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1130 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
1131 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1132 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
1133 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
1135 /* Same nvidia windows driver trouble with white clears as earlier in the same test */
1136 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbeef, 0.0, 0);
1137 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1139 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1140 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1142 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
1143 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
1145 /* Colorwriteenable does not affect the clear */
1146 color = getPixelColor(device, 320, 240);
1147 ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
1149 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1151 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
1152 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1154 rect[0].x1 = 0;
1155 rect[0].y1 = 0;
1156 rect[0].x2 = 640;
1157 rect[0].y2 = 480;
1158 hr = IDirect3DDevice9_Clear(device, 0, rect, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
1159 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1161 color = getPixelColor(device, 320, 240);
1162 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), 1),
1163 "Clear with count = 0, rect != NULL has color %08x\n", color);
1165 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1167 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1168 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1169 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1170 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1172 color = getPixelColor(device, 320, 240);
1173 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1174 "Clear with count = 1, rect = NULL has color %08x\n", color);
1176 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1178 /* Test D3DRS_SRGBWRITEENABLE interactions with clears. */
1179 srgb_supported = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
1180 D3DUSAGE_QUERY_SRGBWRITE, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8));
1181 trace("sRGB writing to D3DFMT_A8R8G8B8 is %ssupported.\n", srgb_supported ? "" : "not ");
1182 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1183 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
1185 color = getPixelColor(device, 320, 240);
1186 ok(color_match(color, 0x007f7f7f, 1), "Clear has color %08x.\n", color);
1188 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
1189 ok(SUCCEEDED(hr), "Failed to enable sRGB write, hr %#x.\n", hr);
1191 /* Draw something to make sure the SRGBWRITEENABLE setting is applied. */
1192 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
1193 ok(SUCCEEDED(hr), "Failed to set world matrix, hr %#x.\n", hr);
1194 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
1195 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
1196 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
1197 ok(SUCCEEDED(hr), "Failed to disable z test, hr %#x.\n", hr);
1198 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1199 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
1200 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
1201 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#x.\n", hr);
1202 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
1203 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
1204 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1205 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
1206 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1207 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1208 hr = IDirect3DDevice9_BeginScene(device);
1209 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1210 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad));
1211 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1212 hr = IDirect3DDevice9_EndScene(device);
1213 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1215 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1216 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
1218 color = getPixelColor(device, 320, 240);
1219 ok(color_match(color, 0x00bbbbbb, 1), "Clear has color %08x.\n", color);
1221 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
1222 ok(SUCCEEDED(hr), "Failed to disable sRGB write, hr %#x.\n", hr);
1224 /* Switching to a new render target seems to be enough to make Windows pick
1225 * up on the changed render state. */
1226 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 2, D3DUSAGE_RENDERTARGET,
1227 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
1228 ok(SUCCEEDED(hr), "Failed to create the offscreen render target, hr %#x.\n", hr);
1229 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1230 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
1231 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface0);
1232 ok(SUCCEEDED(hr), "Failed to get offscreen surface, hr %#x.\n", hr);
1233 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface0);
1234 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1236 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1237 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
1239 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1240 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1242 hr = IDirect3DDevice9_StretchRect(device, surface0, NULL, backbuffer, NULL, D3DTEXF_NONE);
1243 ok(SUCCEEDED(hr), "Failed to blit surface, hr %#x.\n", hr);
1245 color = getPixelColor(device, 64, 64);
1246 ok(color_match(color, 0x007f7f7f, 1), "Clear has color %08x.\n", color);
1248 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
1249 ok(SUCCEEDED(hr), "Failed to enable sRGB write, hr %#x.\n", hr);
1251 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface0);
1252 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1254 hr = IDirect3DDevice9_BeginScene(device);
1255 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1256 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad));
1257 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1258 hr = IDirect3DDevice9_EndScene(device);
1259 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1261 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1262 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
1264 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1265 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1267 hr = IDirect3DDevice9_StretchRect(device, surface0, NULL, backbuffer, NULL, D3DTEXF_NONE);
1268 ok(SUCCEEDED(hr), "Failed to blit surface, hr %#x.\n", hr);
1270 color = getPixelColor(device, 320, 240);
1271 ok(color_match(color, 0x00bbbbbb, 1), "Clear has color %08x.\n", color);
1273 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
1274 ok(SUCCEEDED(hr), "Failed to disable sRGB write, hr %#x.\n", hr);
1275 /* Switching to another surface of the same texture is also enough to make
1276 * the setting "stick". */
1277 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface1);
1278 ok(SUCCEEDED(hr), "Failed to get offscreen surface, hr %#x.\n", hr);
1279 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface1);
1280 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1282 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1283 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
1285 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1286 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1288 hr = IDirect3DDevice9_StretchRect(device, surface1, NULL, backbuffer, NULL, D3DTEXF_NONE);
1289 ok(SUCCEEDED(hr), "Failed to blit surface, hr %#x.\n", hr);
1291 color = getPixelColor(device, 320, 240);
1292 ok(color_match(color, 0x007f7f7f, 1), "Clear has color %08x.\n", color);
1294 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1296 IDirect3DSurface9_Release(surface1);
1297 IDirect3DSurface9_Release(surface0);
1298 IDirect3DSurface9_Release(backbuffer);
1299 IDirect3DTexture9_Release(texture);
1300 refcount = IDirect3DDevice9_Release(device);
1301 ok(!refcount, "Device has %u references left.\n", refcount);
1302 done:
1303 IDirect3D9_Release(d3d);
1304 DestroyWindow(window);
1307 static void color_fill_test(void)
1309 IDirect3DSurface9 *surface;
1310 IDirect3DTexture9 *texture;
1311 D3DCOLOR fill_color, color;
1312 DWORD fill_a, expected_a;
1313 IDirect3DDevice9 *device;
1314 IDirect3D9 *d3d;
1315 ULONG refcount;
1316 HWND window;
1317 HRESULT hr;
1318 static const struct
1320 D3DPOOL pool;
1321 DWORD usage;
1322 HRESULT hr;
1324 resource_types[] =
1326 {D3DPOOL_DEFAULT, 0, D3DERR_INVALIDCALL},
1327 {D3DPOOL_DEFAULT, D3DUSAGE_DYNAMIC, D3DERR_INVALIDCALL},
1328 {D3DPOOL_DEFAULT, D3DUSAGE_RENDERTARGET, D3D_OK},
1329 {D3DPOOL_SYSTEMMEM, 0, D3DERR_INVALIDCALL},
1330 {D3DPOOL_MANAGED, 0, D3DERR_INVALIDCALL},
1331 {D3DPOOL_SCRATCH, 0, D3DERR_INVALIDCALL},
1333 static const struct
1335 D3DFORMAT format;
1336 const char *name;
1337 enum
1339 CHECK_FILL_VALUE = 0x1,
1340 BLOCKS = 0x2,
1341 } flags;
1342 DWORD fill_value;
1344 formats[] =
1346 {D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8", CHECK_FILL_VALUE, 0xdeadbeef},
1347 /* D3DFMT_X8R8G8B8 either set X = A or X = 0, depending on the driver. */
1348 {D3DFMT_R5G6B5, "D3DFMT_R5G6B5", CHECK_FILL_VALUE, 0xadfdadfd},
1349 {D3DFMT_G16R16, "D3DFMT_G16R16", CHECK_FILL_VALUE, 0xbebeadad},
1350 /* Real hardware reliably fills the surface with the blue channel but
1351 * the testbot fills it with 0x00. Wine incorrectly uses the alpha
1352 * channel. Don't bother checking the result because P8 surfaces are
1353 * essentially useless in d3d9. */
1354 {D3DFMT_P8, "D3DFMT_P8", 0, 0xefefefef},
1355 /* Windows drivers produce different results for these formats.
1356 * No driver produces a YUV value that matches the input RGB
1357 * value, and no driver produces a proper DXT compression block.
1359 * Even the clear value 0 does not reliably produce a fill value
1360 * that will return vec4(0.0, 0.0, 0.0, 0.0) when sampled.
1362 * The YUV tests are disabled because they produce a driver-dependent
1363 * result on Wine.
1364 * {D3DFMT_YUY2, "D3DFMT_YUY2", BLOCKS, 0},
1365 * {D3DFMT_UYVY, "D3DFMT_UYVY", BLOCKS, 0}, */
1366 {D3DFMT_DXT1, "D3DFMT_DXT1", BLOCKS, 0x00000000},
1367 /* Vendor-specific formats like ATI2N are a non-issue here since they're not
1368 * supported as offscreen plain surfaces and do not support D3DUSAGE_RENDERTARGET
1369 * when created as texture. */
1371 unsigned int i;
1372 D3DLOCKED_RECT locked_rect;
1373 DWORD *surface_data;
1374 static const RECT rect = {4, 4, 8, 8}, rect2 = {5, 5, 7, 7};
1376 window = create_window();
1377 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1378 ok(!!d3d, "Failed to create a D3D object.\n");
1379 if (!(device = create_device(d3d, window, window, TRUE)))
1381 skip("Failed to create a D3D device, skipping tests.\n");
1382 goto done;
1385 /* Test ColorFill on a the backbuffer (should pass) */
1386 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &surface);
1387 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1389 fill_color = 0x112233;
1390 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1391 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
1393 color = getPixelColor(device, 0, 0);
1394 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
1396 IDirect3DSurface9_Release(surface);
1398 /* Test ColorFill on a render target surface (should pass) */
1399 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8,
1400 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL );
1401 ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
1403 fill_color = 0x445566;
1404 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1405 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
1407 color = getPixelColorFromSurface(surface, 0, 0);
1408 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
1410 IDirect3DSurface9_Release(surface);
1412 /* Test ColorFill on an offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
1413 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1414 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surface, NULL);
1415 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
1417 fill_color = 0x778899;
1418 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1419 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
1421 color = getPixelColorFromSurface(surface, 0, 0);
1422 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
1424 IDirect3DSurface9_Release(surface);
1426 /* Try ColorFill on an offscreen surface in sysmem (should fail) */
1427 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1428 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1429 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
1431 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, 0);
1432 ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
1434 IDirect3DSurface9_Release(surface);
1436 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D16,
1437 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
1438 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr = %08x.\n", hr);
1440 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, 0);
1441 ok(hr == D3DERR_INVALIDCALL, "ColorFill on a depth stencil surface returned hr = %08x.\n", hr);
1443 IDirect3DSurface9_Release(surface);
1445 for (i = 0; i < sizeof(resource_types) / sizeof(resource_types[0]); i++)
1447 texture = NULL;
1448 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, resource_types[i].usage,
1449 D3DFMT_A8R8G8B8, resource_types[i].pool, &texture, NULL);
1450 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, i=%u.\n", hr, i);
1451 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1452 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x, i=%u.\n", hr, i);
1454 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1455 ok(hr == resource_types[i].hr, "Got unexpected hr %#x, expected %#x, i=%u.\n",
1456 hr, resource_types[i].hr, i);
1458 IDirect3DSurface9_Release(surface);
1459 IDirect3DTexture9_Release(texture);
1462 for (i = 0; i < sizeof(formats) / sizeof(formats[0]); i++)
1464 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
1465 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, formats[i].format) != D3D_OK)
1467 skip("Offscreenplain %s surfaces not supported, skipping colorfill test\n", formats[i].name);
1468 continue;
1471 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1472 formats[i].format, D3DPOOL_DEFAULT, &surface, NULL);
1473 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x, fmt=%s.\n", hr, formats[i].name);
1475 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, 0xdeadbeef);
1476 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x, fmt=%s.\n", hr, formats[i].name);
1478 hr = IDirect3DDevice9_ColorFill(device, surface, &rect, 0xdeadbeef);
1479 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x, fmt=%s.\n", hr, formats[i].name);
1481 if (SUCCEEDED(hr))
1483 hr = IDirect3DDevice9_ColorFill(device, surface, &rect2, 0xdeadbeef);
1484 if (formats[i].flags & BLOCKS)
1485 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, fmt=%s.\n", hr, formats[i].name);
1486 else
1487 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x, fmt=%s.\n", hr, formats[i].name);
1490 if (formats[i].flags & CHECK_FILL_VALUE)
1492 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, D3DLOCK_READONLY);
1493 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x, fmt=%s.\n", hr, formats[i].name);
1494 surface_data = locked_rect.pBits;
1495 fill_a = (surface_data[0] & 0xff000000) >> 24;
1496 expected_a = (formats[i].fill_value & 0xff000000) >> 24;
1497 /* Windows drivers disagree on how to promote the 8 bit per channel
1498 * input argument to 16 bit for D3DFMT_G16R16. */
1499 ok(color_match(surface_data[0], formats[i].fill_value, 2) &&
1500 abs((expected_a) - (fill_a)) < 3,
1501 "Expected clear value 0x%08x, got 0x%08x, fmt=%s.\n",
1502 formats[i].fill_value, surface_data[0], formats[i].name);
1503 hr = IDirect3DSurface9_UnlockRect(surface);
1504 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, fmt=%s.\n", hr, formats[i].name);
1507 IDirect3DSurface9_Release(surface);
1510 refcount = IDirect3DDevice9_Release(device);
1511 ok(!refcount, "Device has %u references left.\n", refcount);
1512 done:
1513 IDirect3D9_Release(d3d);
1514 DestroyWindow(window);
1518 * c7 mova ARGB mov ARGB
1519 * -2.4 -2 0x00ffff00 -3 0x00ff0000
1520 * -1.6 -2 0x00ffff00 -2 0x00ffff00
1521 * -0.4 0 0x0000ffff -1 0x0000ff00
1522 * 0.4 0 0x0000ffff 0 0x0000ffff
1523 * 1.6 2 0x00ff00ff 1 0x000000ff
1524 * 2.4 2 0x00ff00ff 2 0x00ff00ff
1526 static void test_mova(void)
1528 IDirect3DVertexDeclaration9 *vertex_declaration;
1529 IDirect3DVertexShader9 *mova_shader;
1530 IDirect3DVertexShader9 *mov_shader;
1531 IDirect3DDevice9 *device;
1532 unsigned int i, j;
1533 IDirect3D9 *d3d;
1534 ULONG refcount;
1535 D3DCAPS9 caps;
1536 HWND window;
1537 HRESULT hr;
1539 static const DWORD mova_test[] =
1541 0xfffe0200, /* vs_2_0 */
1542 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1543 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
1544 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
1545 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
1546 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
1547 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
1548 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
1549 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
1550 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
1551 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
1552 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1553 0x0000ffff /* END */
1555 static const DWORD mov_test[] =
1557 0xfffe0101, /* vs_1_1 */
1558 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1559 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
1560 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
1561 0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
1562 0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
1563 0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
1564 0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
1565 0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
1566 0x00000001, 0xb0010000, 0xa0000007, /* mov a0.x, c7.x */
1567 0x00000001, 0xd00f0000, 0xa0e42003, /* mov oD0, c[a0.x + 3] */
1568 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1569 0x0000ffff /* END */
1571 static const struct
1573 float in[4];
1574 DWORD out;
1576 test_data[2][6] =
1579 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
1580 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
1581 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
1582 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
1583 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
1584 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
1587 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
1588 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
1589 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
1590 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
1591 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
1592 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
1595 static const struct vec3 quad[] =
1597 {-1.0f, -1.0f, 0.0f},
1598 {-1.0f, 1.0f, 0.0f},
1599 { 1.0f, -1.0f, 0.0f},
1600 { 1.0f, 1.0f, 0.0f},
1602 static const D3DVERTEXELEMENT9 decl_elements[] =
1604 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1605 D3DDECL_END()
1608 window = create_window();
1609 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1610 ok(!!d3d, "Failed to create a D3D object.\n");
1611 if (!(device = create_device(d3d, window, window, TRUE)))
1613 skip("Failed to create a D3D device, skipping tests.\n");
1614 goto done;
1617 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1618 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1619 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
1621 skip("No vs_2_0 support, skipping tests.\n");
1622 IDirect3DDevice9_Release(device);
1623 goto done;
1626 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
1627 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1628 hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
1629 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1630 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1631 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1632 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1633 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1635 hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
1636 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1637 for (j = 0; j < sizeof(test_data) / sizeof(*test_data); ++j)
1639 for (i = 0; i < sizeof(*test_data) / sizeof(**test_data); ++i)
1641 DWORD color;
1643 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
1644 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
1646 hr = IDirect3DDevice9_BeginScene(device);
1647 ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
1649 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
1650 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1652 hr = IDirect3DDevice9_EndScene(device);
1653 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
1655 color = getPixelColor(device, 320, 240);
1656 ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
1657 test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
1659 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1660 ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
1662 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1663 ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
1665 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
1666 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1669 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1670 IDirect3DVertexShader9_Release(mova_shader);
1671 IDirect3DVertexShader9_Release(mov_shader);
1672 refcount = IDirect3DDevice9_Release(device);
1673 ok(!refcount, "Device has %u references left.\n", refcount);
1674 done:
1675 IDirect3D9_Release(d3d);
1676 DestroyWindow(window);
1679 static void fog_test(void)
1681 float start = 0.0f, end = 1.0f;
1682 IDirect3DDevice9 *device;
1683 IDirect3D9 *d3d;
1684 D3DCOLOR color;
1685 ULONG refcount;
1686 D3DCAPS9 caps;
1687 HWND window;
1688 HRESULT hr;
1689 int i;
1691 /* Gets full z based fog with linear fog, no fog with specular color. */
1692 static const struct
1694 float x, y, z;
1695 D3DCOLOR diffuse;
1696 D3DCOLOR specular;
1698 untransformed_1[] =
1700 {-1.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
1701 {-1.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
1702 { 0.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
1703 { 0.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
1705 /* Ok, I am too lazy to deal with transform matrices. */
1706 untransformed_2[] =
1708 {-1.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
1709 {-1.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
1710 { 0.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
1711 { 0.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
1713 untransformed_3[] =
1715 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1716 {-1.0f, 1.0f, 0.5f, 0xffff0000, 0xff000000},
1717 { 1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1718 { 1.0f, 1.0f, 0.5f, 0xffff0000, 0xff000000},
1720 far_quad1[] =
1722 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1723 {-1.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
1724 { 0.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
1725 { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1727 far_quad2[] =
1729 {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1730 {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
1731 { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
1732 { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1734 /* Untransformed ones. Give them a different diffuse color to make the
1735 * test look nicer. It also makes making sure that they are drawn
1736 * correctly easier. */
1737 static const struct
1739 float x, y, z, rhw;
1740 D3DCOLOR diffuse;
1741 D3DCOLOR specular;
1743 transformed_1[] =
1745 {320.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1746 {640.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1747 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1748 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1750 transformed_2[] =
1752 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1753 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1754 {640.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1755 {320.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1757 static const struct
1759 struct vec3 position;
1760 DWORD diffuse;
1762 rev_fog_quads[] =
1764 {{-1.0f, -1.0f, 0.1f}, 0x000000ff},
1765 {{-1.0f, 0.0f, 0.1f}, 0x000000ff},
1766 {{ 0.0f, 0.0f, 0.1f}, 0x000000ff},
1767 {{ 0.0f, -1.0f, 0.1f}, 0x000000ff},
1769 {{ 0.0f, -1.0f, 0.9f}, 0x000000ff},
1770 {{ 0.0f, 0.0f, 0.9f}, 0x000000ff},
1771 {{ 1.0f, 0.0f, 0.9f}, 0x000000ff},
1772 {{ 1.0f, -1.0f, 0.9f}, 0x000000ff},
1774 {{ 0.0f, 0.0f, 0.4f}, 0x000000ff},
1775 {{ 0.0f, 1.0f, 0.4f}, 0x000000ff},
1776 {{ 1.0f, 1.0f, 0.4f}, 0x000000ff},
1777 {{ 1.0f, 0.0f, 0.4f}, 0x000000ff},
1779 {{-1.0f, 0.0f, 0.7f}, 0x000000ff},
1780 {{-1.0f, 1.0f, 0.7f}, 0x000000ff},
1781 {{ 0.0f, 1.0f, 0.7f}, 0x000000ff},
1782 {{ 0.0f, 0.0f, 0.7f}, 0x000000ff},
1784 static const D3DMATRIX ident_mat =
1786 1.0f, 0.0f, 0.0f, 0.0f,
1787 0.0f, 1.0f, 0.0f, 0.0f,
1788 0.0f, 0.0f, 1.0f, 0.0f,
1789 0.0f, 0.0f, 0.0f, 1.0f
1790 }}};
1791 static const D3DMATRIX world_mat1 =
1793 1.0f, 0.0f, 0.0f, 0.0f,
1794 0.0f, 1.0f, 0.0f, 0.0f,
1795 0.0f, 0.0f, 1.0f, 0.0f,
1796 0.0f, 0.0f, -0.5f, 1.0f
1797 }}};
1798 static const D3DMATRIX world_mat2 =
1800 1.0f, 0.0f, 0.0f, 0.0f,
1801 0.0f, 1.0f, 0.0f, 0.0f,
1802 0.0f, 0.0f, 1.0f, 0.0f,
1803 0.0f, 0.0f, 1.0f, 1.0f
1804 }}};
1805 static const D3DMATRIX proj_mat =
1807 1.0f, 0.0f, 0.0f, 0.0f,
1808 0.0f, 1.0f, 0.0f, 0.0f,
1809 0.0f, 0.0f, 1.0f, 0.0f,
1810 0.0f, 0.0f, -1.0f, 1.0f
1811 }}};
1812 static const WORD Indices[] = {0, 1, 2, 2, 3, 0};
1813 static const WORD Indices2[] =
1815 0, 1, 2, 2, 3, 0,
1816 4, 5, 6, 6, 7, 4,
1817 8, 9, 10, 10, 11, 8,
1818 12, 13, 14, 14, 15, 12,
1821 window = create_window();
1822 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1823 ok(!!d3d, "Failed to create a D3D object.\n");
1824 if (!(device = create_device(d3d, window, window, TRUE)))
1826 skip("Failed to create a D3D device, skipping tests.\n");
1827 goto done;
1830 memset(&caps, 0, sizeof(caps));
1831 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1832 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
1833 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1834 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1836 /* Setup initial states: No lighting, fog on, fog color */
1837 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
1838 ok(SUCCEEDED(hr), "Failed to disable D3DRS_ZENABLE, hr %#x.\n", hr);
1839 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1840 ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
1841 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1842 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
1843 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xff00ff00 /* A nice green */);
1844 ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
1845 /* Some of the tests seem to depend on the projection matrix explicitly
1846 * being set to an identity matrix, even though that's the default.
1847 * (AMD Radeon HD 6310, Windows 7) */
1848 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
1849 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
1851 /* First test: Both table fog and vertex fog off */
1852 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1853 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
1854 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1855 ok(hr == D3D_OK, "Turning off vertex fog returned %08x\n", hr);
1857 /* Start = 0, end = 1. Should be default, but set them */
1858 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1859 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1860 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1861 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1863 hr = IDirect3DDevice9_BeginScene(device);
1864 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1866 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1867 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1869 /* Untransformed, vertex fog = NONE, table fog = NONE:
1870 * Read the fog weighting from the specular color. */
1871 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1872 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1873 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1875 /* That makes it use the Z value */
1876 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1877 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex mode, hr %#x.\n", hr);
1878 /* Untransformed, vertex fog != none (or table fog != none):
1879 * Use the Z value as input into the equation. */
1880 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1881 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1882 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1884 /* transformed verts */
1885 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1886 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1887 /* Transformed, vertex fog != NONE, pixel fog == NONE:
1888 * Use specular color alpha component. */
1889 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1890 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_1, sizeof(transformed_1[0]));
1891 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1893 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1894 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog table mode, hr %#x.\n", hr);
1895 /* Transformed, table fog != none, vertex anything:
1896 * Use Z value as input to the fog equation. */
1897 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1898 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_2, sizeof(transformed_2[0]));
1899 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1901 hr = IDirect3DDevice9_EndScene(device);
1902 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1904 color = getPixelColor(device, 160, 360);
1905 ok(color == 0x00ff0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1906 color = getPixelColor(device, 160, 120);
1907 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
1908 color = getPixelColor(device, 480, 120);
1909 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1910 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1912 color = getPixelColor(device, 480, 360);
1913 ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
1915 else
1917 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1918 * The settings above result in no fogging with vertex fog
1920 color = getPixelColor(device, 480, 120);
1921 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1922 trace("Info: Table fog not supported by this device\n");
1924 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1926 /* Now test the special case fogstart == fogend */
1927 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1928 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1930 hr = IDirect3DDevice9_BeginScene(device);
1931 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1933 start = 512;
1934 end = 512;
1935 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
1936 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#x.\n", hr);
1937 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
1938 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#x.\n", hr);
1940 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1941 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1942 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1943 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex mode, hr %#x.\n", hr);
1944 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1945 ok(SUCCEEDED(hr), "Failed to set D3DFOG_NONE fog table mode, hr %#x.\n", hr);
1947 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512.
1948 * Would result in a completely fog-free primitive because start > zcoord,
1949 * but because start == end, the primitive is fully covered by fog. The
1950 * same happens to the 2nd untransformed quad with z = 1.0. The third
1951 * transformed quad remains unfogged because the fogcoords are read from
1952 * the specular color and has fixed fogstart and fogend. */
1953 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1954 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1955 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1956 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1957 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1958 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1960 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1961 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1962 /* Transformed, vertex fog != NONE, pixel fog == NONE:
1963 * Use specular color alpha component. */
1964 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1965 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_1, sizeof(transformed_1[0]));
1966 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1968 hr = IDirect3DDevice9_EndScene(device);
1969 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1971 color = getPixelColor(device, 160, 360);
1972 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1973 color = getPixelColor(device, 160, 120);
1974 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1975 color = getPixelColor(device, 480, 120);
1976 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1977 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1979 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1980 * but without shaders it seems to work everywhere
1982 end = 0.2;
1983 start = 0.8;
1984 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1985 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1986 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1987 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1988 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1989 ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1991 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1992 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1993 * so skip this for now
1995 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1996 const char *mode = (i ? "table" : "vertex");
1997 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1998 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1999 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
2000 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2001 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
2002 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2003 hr = IDirect3DDevice9_BeginScene(device);
2004 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2005 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 16 /* NumVerts */,
2006 8 /* PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads, sizeof(rev_fog_quads[0]));
2007 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2008 hr = IDirect3DDevice9_EndScene(device);
2009 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2011 color = getPixelColor(device, 160, 360);
2012 ok(color_match(color, 0x0000ff00, 1),
2013 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
2015 color = getPixelColor(device, 160, 120);
2016 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
2017 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
2019 color = getPixelColor(device, 480, 120);
2020 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
2021 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
2023 color = getPixelColor(device, 480, 360);
2024 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
2026 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2028 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
2029 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
2030 break;
2034 if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
2036 /* A simple fog + non-identity world matrix test */
2037 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat1);
2038 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %#08x\n", hr);
2040 start = 0.0;
2041 end = 1.0;
2042 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
2043 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
2044 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
2045 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
2046 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
2047 ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
2048 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
2049 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
2051 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2052 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %#08x\n", hr);
2054 hr = IDirect3DDevice9_BeginScene(device);
2055 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2057 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
2058 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
2060 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2061 2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
2062 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2063 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2064 2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
2065 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2067 hr = IDirect3DDevice9_EndScene(device);
2068 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2070 color = getPixelColor(device, 160, 360);
2071 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 4),
2072 "Unfogged quad has color %08x\n", color);
2073 color = getPixelColor(device, 160, 120);
2074 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2075 "Fogged out quad has color %08x\n", color);
2077 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2079 /* Test fog behavior with an orthogonal (but non-identity) projection matrix */
2080 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat2);
2081 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
2082 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &proj_mat);
2083 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
2085 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2086 ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
2088 hr = IDirect3DDevice9_BeginScene(device);
2089 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2091 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
2092 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
2094 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2095 2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
2096 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2097 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2098 2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
2099 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2101 hr = IDirect3DDevice9_EndScene(device);
2102 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2104 color = getPixelColor(device, 160, 360);
2105 ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
2106 color = getPixelColor(device, 160, 120);
2107 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2108 "Fogged out quad has color %08x\n", color);
2110 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2112 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &ident_mat);
2113 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
2114 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
2115 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
2117 else
2119 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
2122 /* Test RANGEFOG vs FOGTABLEMODE */
2123 if ((caps.RasterCaps & (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE)) ==
2124 (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE))
2126 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2127 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
2128 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
2129 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
2131 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, TRUE);
2132 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
2134 /* z=0.5, x = +/- 1.0, y = +/- 1.0. In case of z fog the fog coordinate is
2135 * 0.5. With range fog it is sqrt(x*x + y*y + z*z) = 1.5 for all vertices.
2136 * Note that the fog coordinate is interpolated linearly across the vertices,
2137 * so the different eye distance at the screen center should not matter. */
2138 start = 0.75f;
2139 end = 0.75001f;
2140 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
2141 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
2142 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
2143 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
2145 /* Table fog: Range fog is not used */
2146 hr = IDirect3DDevice9_BeginScene(device);
2147 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2149 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
2150 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog table mode, hr %#x.\n", hr);
2151 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
2152 untransformed_3, sizeof(*untransformed_3));
2153 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2155 hr = IDirect3DDevice9_EndScene(device);
2156 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2158 color = getPixelColor(device, 10, 10);
2159 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2160 color = getPixelColor(device, 630, 10);
2161 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2162 color = getPixelColor(device, 10, 470);
2163 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2164 color = getPixelColor(device, 630, 470);
2165 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2167 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2168 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
2170 /* Vertex fog: Rangefog is used */
2171 hr = IDirect3DDevice9_BeginScene(device);
2172 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2174 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
2175 ok(SUCCEEDED(hr), "Failed to set D3DFOG_NONE fog table mode, hr %#x.\n", hr);
2176 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
2177 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex mode, hr %#x.\n", hr);
2178 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
2179 untransformed_3, sizeof(*untransformed_3));
2180 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2182 hr = IDirect3DDevice9_EndScene(device);
2183 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2185 color = getPixelColor(device, 10, 10);
2186 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2187 "Rangefog with vertex fog returned color 0x%08x\n", color);
2188 color = getPixelColor(device, 630, 10);
2189 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2190 "Rangefog with vertex fog returned color 0x%08x\n", color);
2191 color = getPixelColor(device, 10, 470);
2192 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2193 "Rangefog with vertex fog returned color 0x%08x\n", color);
2194 color = getPixelColor(device, 630, 470);
2195 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2196 "Rangefog with vertex fog returned color 0x%08x\n", color);
2198 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2199 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
2201 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, FALSE);
2202 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
2204 else
2206 skip("Range fog or table fog not supported, skipping range fog tests\n");
2209 refcount = IDirect3DDevice9_Release(device);
2210 ok(!refcount, "Device has %u references left.\n", refcount);
2211 done:
2212 IDirect3D9_Release(d3d);
2213 DestroyWindow(window);
2216 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
2217 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
2218 * regardless of the actual addressing mode set. The way this test works is
2219 * that we sample in one of the corners of the cubemap with filtering enabled,
2220 * and check the interpolated color. There are essentially two reasonable
2221 * things an implementation can do: Either pick one of the faces and
2222 * interpolate the edge texel with itself (i.e., clamp within the face), or
2223 * interpolate between the edge texels of the three involved faces. It should
2224 * never involve the border color or the other side (texcoord wrapping) of a
2225 * face in the interpolation. */
2226 static void test_cube_wrap(void)
2228 IDirect3DVertexDeclaration9 *vertex_declaration;
2229 IDirect3DSurface9 *face_surface, *surface;
2230 IDirect3DCubeTexture9 *texture;
2231 D3DLOCKED_RECT locked_rect;
2232 IDirect3DDevice9 *device;
2233 unsigned int x, y, face;
2234 IDirect3D9 *d3d;
2235 ULONG refcount;
2236 D3DCAPS9 caps;
2237 HWND window;
2238 HRESULT hr;
2240 static const float quad[][6] =
2242 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2243 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2244 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2245 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2247 static const D3DVERTEXELEMENT9 decl_elements[] =
2249 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2250 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2251 D3DDECL_END()
2253 static const struct
2255 D3DTEXTUREADDRESS mode;
2256 const char *name;
2258 address_modes[] =
2260 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
2261 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
2262 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
2263 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
2264 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
2267 window = create_window();
2268 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2269 ok(!!d3d, "Failed to create a D3D object.\n");
2270 if (!(device = create_device(d3d, window, window, TRUE)))
2272 skip("Failed to create a D3D device, skipping tests.\n");
2273 goto done;
2276 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2277 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2278 if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP))
2280 skip("No cube texture support, skipping tests.\n");
2281 IDirect3DDevice9_Release(device);
2282 goto done;
2285 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
2286 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
2287 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2288 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
2290 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
2291 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
2292 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
2294 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
2295 D3DPOOL_DEFAULT, &texture, NULL);
2296 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
2298 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
2299 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2301 for (y = 0; y < 128; ++y)
2303 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2304 for (x = 0; x < 64; ++x)
2306 *ptr++ = 0xff0000ff;
2308 for (x = 64; x < 128; ++x)
2310 *ptr++ = 0xffff0000;
2314 hr = IDirect3DSurface9_UnlockRect(surface);
2315 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2317 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
2318 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
2320 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
2321 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
2323 IDirect3DSurface9_Release(face_surface);
2325 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
2326 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2328 for (y = 0; y < 128; ++y)
2330 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2331 for (x = 0; x < 64; ++x)
2333 *ptr++ = 0xffff0000;
2335 for (x = 64; x < 128; ++x)
2337 *ptr++ = 0xff0000ff;
2341 hr = IDirect3DSurface9_UnlockRect(surface);
2342 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2344 /* Create cube faces */
2345 for (face = 1; face < 6; ++face)
2347 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
2348 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
2350 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
2351 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
2353 IDirect3DSurface9_Release(face_surface);
2356 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
2357 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2359 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
2360 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2361 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
2362 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2363 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
2364 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
2366 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2367 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2369 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
2371 DWORD color;
2373 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
2374 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
2375 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
2376 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
2378 hr = IDirect3DDevice9_BeginScene(device);
2379 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2381 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2382 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2384 hr = IDirect3DDevice9_EndScene(device);
2385 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2387 color = getPixelColor(device, 320, 240);
2388 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
2389 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
2390 color, address_modes[x].name);
2392 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2393 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2395 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
2396 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
2399 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2400 IDirect3DCubeTexture9_Release(texture);
2401 IDirect3DSurface9_Release(surface);
2402 refcount = IDirect3DDevice9_Release(device);
2403 ok(!refcount, "Device has %u references left.\n", refcount);
2404 done:
2405 IDirect3D9_Release(d3d);
2406 DestroyWindow(window);
2409 static void offscreen_test(void)
2411 IDirect3DSurface9 *backbuffer, *offscreen;
2412 IDirect3DTexture9 *offscreenTexture;
2413 IDirect3DDevice9 *device;
2414 IDirect3D9 *d3d;
2415 D3DCOLOR color;
2416 ULONG refcount;
2417 HWND window;
2418 HRESULT hr;
2420 static const float quad[][5] =
2422 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
2423 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
2424 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
2425 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
2428 window = create_window();
2429 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2430 ok(!!d3d, "Failed to create a D3D object.\n");
2431 if (!(device = create_device(d3d, window, window, TRUE)))
2433 skip("Failed to create a D3D device, skipping tests.\n");
2434 goto done;
2437 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
2438 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
2440 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2441 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
2442 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
2443 if (!offscreenTexture)
2445 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5.\n");
2446 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2447 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
2448 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
2449 if (!offscreenTexture)
2451 skip("Cannot create an offscreen render target.\n");
2452 IDirect3DDevice9_Release(device);
2453 goto done;
2457 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2458 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2460 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
2461 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
2463 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2464 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
2466 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
2467 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
2468 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2469 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
2470 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2471 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2472 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2473 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2474 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2475 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2477 hr = IDirect3DDevice9_BeginScene(device);
2478 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2480 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
2481 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2482 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 1.0f, 0);
2483 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2485 /* Draw without textures - Should result in a white quad. */
2486 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2487 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2489 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
2490 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2491 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)offscreenTexture);
2492 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2494 /* This time with the texture. */
2495 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2496 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2498 hr = IDirect3DDevice9_EndScene(device);
2499 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2501 /* Center quad - should be white */
2502 color = getPixelColor(device, 320, 240);
2503 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2504 /* Some quad in the cleared part of the texture */
2505 color = getPixelColor(device, 170, 240);
2506 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
2507 /* Part of the originally cleared back buffer */
2508 color = getPixelColor(device, 10, 10);
2509 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2510 color = getPixelColor(device, 10, 470);
2511 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2513 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2515 IDirect3DSurface9_Release(backbuffer);
2516 IDirect3DTexture9_Release(offscreenTexture);
2517 IDirect3DSurface9_Release(offscreen);
2518 refcount = IDirect3DDevice9_Release(device);
2519 ok(!refcount, "Device has %u references left.\n", refcount);
2520 done:
2521 IDirect3D9_Release(d3d);
2522 DestroyWindow(window);
2525 /* This test tests fog in combination with shaders.
2526 * What's tested: linear fog (vertex and table) with pixel shader
2527 * linear table fog with non foggy vertex shader
2528 * vertex fog with foggy vertex shader, non-linear
2529 * fog with shader, non-linear fog with foggy shader,
2530 * linear table fog with foggy shader */
2531 static void fog_with_shader_test(void)
2533 IDirect3DVertexShader9 *vertex_shader[4] = {NULL, NULL, NULL, NULL};
2534 IDirect3DPixelShader9 *pixel_shader[3] = {NULL, NULL, NULL};
2535 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
2536 IDirect3DDevice9 *device;
2537 unsigned int i, j;
2538 IDirect3D9 *d3d;
2539 ULONG refcount;
2540 D3DCAPS9 caps;
2541 DWORD color;
2542 HWND window;
2543 HRESULT hr;
2544 union
2546 float f;
2547 DWORD i;
2548 } start, end;
2550 /* basic vertex shader without fog computation ("non foggy") */
2551 static const DWORD vertex_shader_code1[] =
2553 0xfffe0101, /* vs_1_1 */
2554 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2555 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
2556 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2557 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
2558 0x0000ffff
2560 /* basic vertex shader with reversed fog computation ("foggy") */
2561 static const DWORD vertex_shader_code2[] =
2563 0xfffe0101, /* vs_1_1 */
2564 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2565 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
2566 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
2567 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2568 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
2569 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
2570 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
2571 0x0000ffff
2573 /* basic vertex shader with reversed fog computation ("foggy"), vs_2_0 */
2574 static const DWORD vertex_shader_code3[] =
2576 0xfffe0200, /* vs_2_0 */
2577 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2578 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
2579 0x05000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
2580 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2581 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
2582 0x03000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
2583 0x03000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
2584 0x0000ffff
2586 /* basic pixel shader */
2587 static const DWORD pixel_shader_code[] =
2589 0xffff0101, /* ps_1_1 */
2590 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
2591 0x0000ffff
2593 static const DWORD pixel_shader_code2[] =
2595 0xffff0200, /* ps_2_0 */
2596 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
2597 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
2598 0x0000ffff
2600 struct
2602 struct vec3 position;
2603 DWORD diffuse;
2605 quad[] =
2607 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
2608 {{-1.0f, 1.0f, 0.0f}, 0xffff0000},
2609 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
2610 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000},
2612 static const D3DVERTEXELEMENT9 decl_elements[] =
2614 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2615 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
2616 D3DDECL_END()
2618 /* This reference data was collected on a nVidia GeForce 7600GS driver
2619 * version 84.19 DirectX version 9.0c on Windows XP. */
2620 static const struct test_data_t
2622 int vshader;
2623 int pshader;
2624 D3DFOGMODE vfog;
2625 D3DFOGMODE tfog;
2626 unsigned int color[11];
2628 test_data[] =
2630 /* only pixel shader: */
2631 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
2632 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2633 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2634 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
2635 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2636 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2637 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
2638 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2639 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2640 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2641 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2642 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2643 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
2644 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2645 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2647 /* vertex shader */
2648 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
2649 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2650 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2651 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
2652 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2653 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2654 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
2655 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2656 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2658 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
2659 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2660 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2661 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
2662 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2663 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2665 /* vertex shader and pixel shader */
2666 /* The next 4 tests would read the fog coord output, but it isn't available.
2667 * The result is a fully fogged quad, no matter what the Z coord is. This is on
2668 * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
2669 * These tests should be disabled if some other hardware behaves differently
2671 {1, 1, D3DFOG_NONE, D3DFOG_NONE,
2672 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2673 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2674 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2675 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2676 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2677 {1, 1, D3DFOG_EXP, D3DFOG_NONE,
2678 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2679 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2680 {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
2681 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2682 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2684 /* These use the Z coordinate with linear table fog */
2685 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
2686 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2687 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2688 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
2689 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2690 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2691 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
2692 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2693 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2694 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
2695 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2696 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2698 /* Non-linear table fog without fog coord */
2699 {1, 1, D3DFOG_NONE, D3DFOG_EXP,
2700 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
2701 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
2702 {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
2703 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
2704 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
2706 /* These tests fail on older Nvidia drivers */
2707 /* foggy vertex shader */
2708 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
2709 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2710 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2711 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
2712 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2713 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2714 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
2715 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2716 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2717 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
2718 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2719 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2721 {3, 0, D3DFOG_NONE, D3DFOG_NONE,
2722 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2723 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2724 {3, 0, D3DFOG_EXP, D3DFOG_NONE,
2725 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2726 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2727 {3, 0, D3DFOG_EXP2, D3DFOG_NONE,
2728 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2729 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2730 {3, 0, D3DFOG_LINEAR, D3DFOG_NONE,
2731 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2732 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2734 /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
2735 * all using the fixed fog-coord linear fog
2737 /* vs_1_1 with ps_1_1 */
2738 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
2739 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2740 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2741 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
2742 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2743 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2744 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
2745 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2746 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2747 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2748 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2749 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2751 /* vs_2_0 with ps_1_1 */
2752 {3, 1, D3DFOG_NONE, D3DFOG_NONE,
2753 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2754 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2755 {3, 1, D3DFOG_EXP, D3DFOG_NONE,
2756 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2757 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2758 {3, 1, D3DFOG_EXP2, D3DFOG_NONE,
2759 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2760 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2761 {3, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2762 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2763 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2765 /* vs_1_1 with ps_2_0 */
2766 {2, 2, D3DFOG_NONE, D3DFOG_NONE,
2767 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2768 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2769 {2, 2, D3DFOG_EXP, D3DFOG_NONE,
2770 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2771 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2772 {2, 2, D3DFOG_EXP2, D3DFOG_NONE,
2773 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2774 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2775 {2, 2, D3DFOG_LINEAR, D3DFOG_NONE,
2776 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2777 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2779 /* vs_2_0 with ps_2_0 */
2780 {3, 2, D3DFOG_NONE, D3DFOG_NONE,
2781 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2782 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2783 {3, 2, D3DFOG_EXP, D3DFOG_NONE,
2784 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2785 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2786 {3, 2, D3DFOG_EXP2, D3DFOG_NONE,
2787 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2788 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2789 {3, 2, D3DFOG_LINEAR, D3DFOG_NONE,
2790 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2791 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2793 /* These use table fog. Here the shader-provided fog coordinate is
2794 * ignored and the z coordinate used instead
2796 {2, 1, D3DFOG_NONE, D3DFOG_EXP,
2797 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
2798 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
2799 {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
2800 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
2801 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
2802 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
2803 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2804 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2806 static const D3DMATRIX identity =
2808 1.0f, 0.0f, 0.0f, 0.0f,
2809 0.0f, 1.0f, 0.0f, 0.0f,
2810 0.0f, 0.0f, 1.0f, 0.0f,
2811 0.0f, 0.0f, 0.0f, 1.0f,
2812 }}};
2814 window = create_window();
2815 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2816 ok(!!d3d, "Failed to create a D3D object.\n");
2817 if (!(device = create_device(d3d, window, window, TRUE)))
2819 skip("Failed to create a D3D device, skipping tests.\n");
2820 goto done;
2823 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2824 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2825 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0) || caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
2827 skip("No shader model 2 support, skipping tests.\n");
2828 IDirect3DDevice9_Release(device);
2829 goto done;
2832 /* NOTE: Changing these values will not affect the tests with foggy vertex
2833 * shader, as the values are hardcoded in the shader. */
2834 start.f = 0.1f;
2835 end.f = 0.9f;
2837 /* Some of the tests seem to depend on the projection matrix explicitly
2838 * being set to an identity matrix, even though that's the default.
2839 * (AMD Radeon HD 6310, Windows 7) */
2840 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
2841 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
2843 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
2844 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2845 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
2846 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2847 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code3, &vertex_shader[3]);
2848 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2849 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
2850 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2851 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code2, &pixel_shader[2]);
2852 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2853 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
2854 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
2856 /* Setup initial states: No lighting, fog on, fog color */
2857 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2858 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
2859 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
2860 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
2861 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xff00ff00 /* A nice green */);
2862 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
2863 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2864 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2866 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
2867 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
2868 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
2869 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
2871 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
2872 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
2873 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
2874 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
2875 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
2877 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
2879 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
2880 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2881 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
2882 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2883 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
2884 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2885 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
2886 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2888 for(j=0; j < 11; j++)
2890 /* Don't use the whole zrange to prevent rounding errors */
2891 quad[0].position.z = 0.001f + (float)j / 10.02f;
2892 quad[1].position.z = 0.001f + (float)j / 10.02f;
2893 quad[2].position.z = 0.001f + (float)j / 10.02f;
2894 quad[3].position.z = 0.001f + (float)j / 10.02f;
2896 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff00ff, 1.0f, 0);
2897 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2899 hr = IDirect3DDevice9_BeginScene(device);
2900 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
2902 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2903 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2905 hr = IDirect3DDevice9_EndScene(device);
2906 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
2908 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
2909 color = getPixelColor(device, 128, 240);
2910 ok(color_match(color, test_data[i].color[j], 13),
2911 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
2912 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
2915 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2917 IDirect3DVertexShader9_Release(vertex_shader[1]);
2918 IDirect3DVertexShader9_Release(vertex_shader[2]);
2919 IDirect3DVertexShader9_Release(vertex_shader[3]);
2920 IDirect3DPixelShader9_Release(pixel_shader[1]);
2921 IDirect3DPixelShader9_Release(pixel_shader[2]);
2922 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2923 refcount = IDirect3DDevice9_Release(device);
2924 ok(!refcount, "Device has %u references left.\n", refcount);
2925 done:
2926 IDirect3D9_Release(d3d);
2927 DestroyWindow(window);
2930 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
2931 unsigned int i, x, y;
2932 HRESULT hr;
2933 IDirect3DTexture9 *texture[2] = {NULL, NULL};
2934 D3DLOCKED_RECT locked_rect;
2936 /* Generate the textures */
2937 for(i=0; i<2; i++)
2939 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
2940 D3DPOOL_MANAGED, &texture[i], NULL);
2941 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
2943 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
2944 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2945 for (y = 0; y < 128; ++y)
2947 if(i)
2948 { /* Set up black texture with 2x2 texel white spot in the middle */
2949 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2950 for (x = 0; x < 128; ++x)
2952 *ptr++ = D3DCOLOR_ARGB(0xff, x * 2, y * 2, 0);
2955 else
2956 { /* Set up a displacement map which points away from the center parallel to the closest axis.
2957 * (if multiplied with bumpenvmat)
2959 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2960 for (x = 0; x < 128; ++x)
2962 if(abs(x-64)>abs(y-64))
2964 if(x < 64)
2965 *ptr++ = 0xc000;
2966 else
2967 *ptr++ = 0x4000;
2969 else
2971 if(y < 64)
2972 *ptr++ = 0x0040;
2973 else
2974 *ptr++ = 0x00c0;
2979 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
2980 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2982 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
2983 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2985 /* Disable texture filtering */
2986 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2987 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2988 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2989 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2991 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2992 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
2993 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2994 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
2998 /* Test the behavior of the texbem instruction with normal 2D and projective
2999 * 2D textures. */
3000 static void texbem_test(void)
3002 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
3003 /* Use asymmetric matrix to test loading. */
3004 float bumpenvmat[4] = {0.0f, 0.5f, -0.5f, 0.0f};
3005 IDirect3DPixelShader9 *pixel_shader = NULL;
3006 IDirect3DTexture9 *texture1, *texture2;
3007 IDirect3DTexture9 *texture = NULL;
3008 D3DLOCKED_RECT locked_rect;
3009 IDirect3DDevice9 *device;
3010 IDirect3D9 *d3d;
3011 ULONG refcount;
3012 D3DCAPS9 caps;
3013 DWORD color;
3014 HWND window;
3015 HRESULT hr;
3016 int i;
3018 static const DWORD pixel_shader_code[] =
3020 0xffff0101, /* ps_1_1*/
3021 0x00000042, 0xb00f0000, /* tex t0*/
3022 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
3023 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
3024 0x0000ffff
3026 static const DWORD double_texbem_code[] =
3028 0xffff0103, /* ps_1_3 */
3029 0x00000042, 0xb00f0000, /* tex t0 */
3030 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
3031 0x00000042, 0xb00f0002, /* tex t2 */
3032 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
3033 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
3034 0x0000ffff /* end */
3036 static const float quad[][7] =
3038 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
3039 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
3040 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
3041 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
3043 static const float quad_proj[][9] =
3045 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
3046 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
3047 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
3048 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
3050 static const float double_quad[] =
3052 -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3053 -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3054 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3055 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3057 static const D3DVERTEXELEMENT9 decl_elements[][4] =
3060 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3061 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3062 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
3063 D3DDECL_END()
3066 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3067 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3068 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
3069 D3DDECL_END()
3073 window = create_window();
3074 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3075 ok(!!d3d, "Failed to create a D3D object.\n");
3076 if (!(device = create_device(d3d, window, window, TRUE)))
3078 skip("Failed to create a D3D device, skipping tests.\n");
3079 goto done;
3082 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3083 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3084 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
3086 skip("No ps_1_1 support, skipping tests.\n");
3087 IDirect3DDevice9_Release(device);
3088 goto done;
3091 generate_bumpmap_textures(device);
3093 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
3094 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
3095 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
3096 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
3097 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
3099 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
3100 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
3102 for(i=0; i<2; i++)
3104 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
3105 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
3107 if(i)
3109 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
3110 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
3113 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
3114 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
3115 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
3116 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
3118 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
3119 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
3120 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
3121 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3123 hr = IDirect3DDevice9_BeginScene(device);
3124 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
3126 if(!i)
3127 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
3128 else
3129 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
3130 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
3132 hr = IDirect3DDevice9_EndScene(device);
3133 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
3135 /* The Window 8 testbot (WARP) seems to use the transposed
3136 * D3DTSS_BUMPENVMAT matrix. */
3137 color = getPixelColor(device, 160, 240);
3138 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00007e00, 4)),
3139 "Got unexpected color 0x%08x.\n", color);
3140 color = getPixelColor(device, 480, 240);
3141 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00fe7e00, 4)),
3142 "Got unexpected color 0x%08x.\n", color);
3143 color = getPixelColor(device, 320, 120);
3144 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x0080fe00, 4)),
3145 "Got unexpected color 0x%08x.\n", color);
3146 color = getPixelColor(device, 320, 360);
3147 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00800000, 4)),
3148 "Got unexpected color 0x%08x.\n", color);
3150 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3151 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3153 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3154 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3155 IDirect3DPixelShader9_Release(pixel_shader);
3157 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3158 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
3159 IDirect3DVertexDeclaration9_Release(vertex_declaration);
3162 /* clean up */
3163 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
3164 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
3166 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3167 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
3169 for(i=0; i<2; i++)
3171 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
3172 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
3173 IDirect3DTexture9_Release(texture); /* For the GetTexture */
3174 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
3175 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
3176 IDirect3DTexture9_Release(texture);
3179 /* Test double texbem */
3180 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
3181 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
3182 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
3183 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
3184 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
3185 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
3186 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
3187 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
3189 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
3190 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3191 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
3192 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
3194 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3195 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3197 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
3198 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3199 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
3200 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
3201 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
3202 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3205 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
3206 #define tex 0x00ff0000
3207 #define tex1 0x0000ff00
3208 #define origin 0x000000ff
3209 static const DWORD pixel_data[] = {
3210 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3211 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3212 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3213 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3214 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
3215 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3216 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3217 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3219 #undef tex1
3220 #undef tex2
3221 #undef origin
3223 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
3224 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3225 for(i = 0; i < 8; i++) {
3226 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
3228 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
3229 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3232 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3233 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3234 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
3235 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3236 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
3237 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3238 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
3239 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3240 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
3241 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
3242 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
3243 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
3245 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
3246 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
3247 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
3248 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3249 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
3250 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3251 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
3252 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3253 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
3254 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3256 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
3257 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
3258 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
3259 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3260 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
3261 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3262 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
3263 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3264 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
3265 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3267 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3268 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3269 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3270 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3271 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3272 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3273 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3274 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3275 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3276 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3277 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3278 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3279 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3280 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3281 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3282 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3284 hr = IDirect3DDevice9_BeginScene(device);
3285 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3286 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
3287 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
3288 hr = IDirect3DDevice9_EndScene(device);
3289 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3290 /* The Window 8 testbot (WARP) seems to use the transposed
3291 * D3DTSS_BUMPENVMAT matrix. */
3292 color = getPixelColor(device, 320, 240);
3293 ok(color_match(color, 0x00ffff00, 1) || broken(color_match(color, 0x0000ffff, 1)),
3294 "Got unexpected color 0x%08x.\n", color);
3296 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3297 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3299 IDirect3DPixelShader9_Release(pixel_shader);
3300 IDirect3DTexture9_Release(texture);
3301 IDirect3DTexture9_Release(texture1);
3302 IDirect3DTexture9_Release(texture2);
3303 refcount = IDirect3DDevice9_Release(device);
3304 ok(!refcount, "Device has %u references left.\n", refcount);
3305 done:
3306 IDirect3D9_Release(d3d);
3307 DestroyWindow(window);
3310 static void z_range_test(void)
3312 IDirect3DVertexShader9 *shader;
3313 IDirect3DDevice9 *device;
3314 IDirect3D9 *d3d;
3315 ULONG refcount;
3316 D3DCAPS9 caps;
3317 DWORD color;
3318 HWND window;
3319 HRESULT hr;
3321 static const struct
3323 struct vec3 position;
3324 DWORD diffuse;
3326 quad[] =
3328 {{-1.0f, 0.0f, 1.1f}, 0xffff0000},
3329 {{-1.0f, 1.0f, 1.1f}, 0xffff0000},
3330 {{ 1.0f, 0.0f, -1.1f}, 0xffff0000},
3331 {{ 1.0f, 1.0f, -1.1f}, 0xffff0000},
3333 quad2[] =
3335 {{-1.0f, 0.0f, 1.1f}, 0xff0000ff},
3336 {{-1.0f, 1.0f, 1.1f}, 0xff0000ff},
3337 {{ 1.0f, 0.0f, -1.1f}, 0xff0000ff},
3338 {{ 1.0f, 1.0f, -1.1f}, 0xff0000ff},
3340 static const struct
3342 struct vec4 position;
3343 DWORD diffuse;
3345 quad3[] =
3347 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xffffff00},
3348 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xffffff00},
3349 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xffffff00},
3350 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xffffff00},
3352 quad4[] =
3354 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xff00ff00},
3355 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xff00ff00},
3356 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xff00ff00},
3357 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xff00ff00},
3359 static const DWORD shader_code[] =
3361 0xfffe0101, /* vs_1_1 */
3362 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
3363 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
3364 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
3365 0x0000ffff /* end */
3367 static const float color_const_1[] = {1.0f, 0.0f, 0.0f, 1.0f};
3368 static const float color_const_2[] = {0.0f, 0.0f, 1.0f, 1.0f};
3370 window = create_window();
3371 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3372 ok(!!d3d, "Failed to create a D3D object.\n");
3373 if (!(device = create_device(d3d, window, window, TRUE)))
3375 skip("Failed to create a D3D device, skipping tests.\n");
3376 goto done;
3379 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3380 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3382 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
3383 * then call Present. Then clear the color buffer to make sure it has some defined content
3384 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
3385 * by the depth value. */
3386 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75f, 0);
3387 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3388 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3389 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
3390 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
3391 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3393 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3394 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
3395 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
3396 ok(SUCCEEDED(hr), "Failed to enable clipping, hr %#x.\n", hr);
3397 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3398 ok(SUCCEEDED(hr), "Failed to enable z test, hr %#x.\n", hr);
3399 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3400 ok(SUCCEEDED(hr), "Failed to disable z writes, hr %#x.\n", hr);
3401 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3402 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3403 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3404 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
3406 hr = IDirect3DDevice9_BeginScene(device);
3407 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3409 /* Test the untransformed vertex path */
3410 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
3411 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3412 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
3413 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3414 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
3415 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3417 /* Test the transformed vertex path */
3418 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
3419 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
3421 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
3422 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3423 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3424 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3425 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
3426 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3428 hr = IDirect3DDevice9_EndScene(device);
3429 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3431 /* Do not test the exact corner pixels, but go pretty close to them */
3433 /* Clipped because z > 1.0 */
3434 color = getPixelColor(device, 28, 238);
3435 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3436 color = getPixelColor(device, 28, 241);
3437 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
3438 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3439 else
3440 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
3442 /* Not clipped, > z buffer clear value(0.75).
3444 * On the r500 driver on Windows D3DCMP_GREATER and D3DCMP_GREATEREQUAL are broken for depth
3445 * values > 0.5. The range appears to be distorted, apparently an incoming value of ~0.875 is
3446 * equal to a stored depth buffer value of 0.5. */
3447 color = getPixelColor(device, 31, 238);
3448 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3449 color = getPixelColor(device, 31, 241);
3450 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
3451 color = getPixelColor(device, 100, 238);
3452 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
3453 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3454 color = getPixelColor(device, 100, 241);
3455 ok(color_match(color, 0x00ffff00, 0) || broken(color_match(color, 0x00ffffff, 0)),
3456 "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
3458 /* Not clipped, < z buffer clear value */
3459 color = getPixelColor(device, 104, 238);
3460 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3461 color = getPixelColor(device, 104, 241);
3462 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
3463 color = getPixelColor(device, 318, 238);
3464 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3465 color = getPixelColor(device, 318, 241);
3466 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
3468 /* Clipped because z < 0.0 */
3469 color = getPixelColor(device, 321, 238);
3470 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3471 color = getPixelColor(device, 321, 241);
3472 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
3473 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3474 else
3475 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3477 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3478 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
3480 /* Test the shader path */
3481 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
3483 skip("Vertex shaders not supported, skipping tests.\n");
3484 IDirect3DDevice9_Release(device);
3485 goto done;
3487 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
3488 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
3490 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
3491 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3493 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3494 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
3495 hr = IDirect3DDevice9_SetVertexShader(device, shader);
3496 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
3498 hr = IDirect3DDevice9_BeginScene(device);
3499 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3501 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, color_const_1, 1);
3502 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
3503 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
3504 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3506 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
3507 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3508 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, color_const_2, 1);
3509 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
3510 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
3511 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3513 hr = IDirect3DDevice9_EndScene(device);
3514 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3516 IDirect3DVertexShader9_Release(shader);
3518 /* Z < 1.0 */
3519 color = getPixelColor(device, 28, 238);
3520 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3522 /* 1.0 < z < 0.75 */
3523 color = getPixelColor(device, 31, 238);
3524 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3525 color = getPixelColor(device, 100, 238);
3526 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
3527 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3529 /* 0.75 < z < 0.0 */
3530 color = getPixelColor(device, 104, 238);
3531 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3532 color = getPixelColor(device, 318, 238);
3533 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3535 /* 0.0 < z */
3536 color = getPixelColor(device, 321, 238);
3537 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3539 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3540 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
3542 refcount = IDirect3DDevice9_Release(device);
3543 ok(!refcount, "Device has %u references left.\n", refcount);
3544 done:
3545 IDirect3D9_Release(d3d);
3546 DestroyWindow(window);
3549 static void fill_surface(IDirect3DSurface9 *surface, DWORD color, DWORD flags)
3551 D3DSURFACE_DESC desc;
3552 D3DLOCKED_RECT l;
3553 HRESULT hr;
3554 unsigned int x, y;
3555 DWORD *mem;
3557 memset(&desc, 0, sizeof(desc));
3558 memset(&l, 0, sizeof(l));
3559 hr = IDirect3DSurface9_GetDesc(surface, &desc);
3560 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
3561 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, flags);
3562 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
3563 if(FAILED(hr)) return;
3565 for(y = 0; y < desc.Height; y++)
3567 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
3568 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
3570 mem[x] = color;
3573 hr = IDirect3DSurface9_UnlockRect(surface);
3574 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
3577 static void stretchrect_test(void)
3579 IDirect3DSurface9 *surf_tex_rt32, *surf_tex_rt64, *surf_tex_rt_dest64, *surf_tex_rt_dest640_480;
3580 IDirect3DSurface9 *surf_offscreen32, *surf_offscreen64, *surf_offscreen_dest64;
3581 IDirect3DTexture9 *tex_rt32, *tex_rt64, *tex_rt_dest64, *tex_rt_dest640_480;
3582 IDirect3DSurface9 *surf_tex32, *surf_tex64, *surf_tex_dest64;
3583 IDirect3DSurface9 *surf_rt32, *surf_rt64, *surf_rt_dest64;
3584 IDirect3DTexture9 *tex32, *tex64, *tex_dest64;
3585 IDirect3DSurface9 *surf_temp32, *surf_temp64;
3586 IDirect3DSurface9 *backbuffer;
3587 IDirect3DDevice9 *device;
3588 IDirect3D9 *d3d;
3589 D3DCOLOR color;
3590 ULONG refcount;
3591 HWND window;
3592 HRESULT hr;
3594 static const RECT src_rect = {0, 0, 640, 480};
3595 static const RECT src_rect_flipy = {0, 480, 640, 0};
3596 static const RECT dst_rect = {0, 0, 640, 480};
3597 static const RECT dst_rect_flipy = {0, 480, 640, 0};
3598 static const RECT src_rect64 = {0, 0, 64, 64};
3599 static const RECT src_rect64_flipy = {0, 64, 64, 0};
3600 static const RECT dst_rect64 = {0, 0, 64, 64};
3601 static const RECT dst_rect64_flipy = {0, 64, 64, 0};
3603 window = create_window();
3604 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3605 ok(!!d3d, "Failed to create a D3D object.\n");
3606 if (!(device = create_device(d3d, window, window, TRUE)))
3608 skip("Failed to create a D3D device, skipping tests.\n");
3609 goto done;
3612 /* Create our temporary surfaces in system memory. */
3613 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
3614 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
3615 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3616 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
3617 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
3618 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3620 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT. */
3621 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
3622 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
3623 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3624 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
3625 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
3626 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3627 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
3628 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
3629 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3631 /* Create render target surfaces. */
3632 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32,
3633 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
3634 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
3635 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64,
3636 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
3637 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
3638 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64,
3639 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
3640 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
3641 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
3642 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
3644 /* Create render target textures. */
3645 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET,
3646 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
3647 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3648 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET,
3649 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
3650 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3651 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET,
3652 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
3653 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3654 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET,
3655 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
3656 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3657 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
3658 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3659 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
3660 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3661 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
3662 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3663 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
3664 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3666 /* Create regular textures in D3DPOOL_DEFAULT. */
3667 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
3668 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3669 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
3670 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3671 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
3672 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3673 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
3674 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3675 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
3676 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3677 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
3678 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3680 /**********************************************************************
3681 * Tests for when the source parameter is an offscreen plain surface. *
3682 **********************************************************************/
3684 /* Fill the offscreen 64x64 surface with green. */
3685 fill_surface(surf_offscreen64, 0xff00ff00, 0);
3687 /* offscreenplain ==> offscreenplain, same size. */
3688 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, D3DTEXF_NONE);
3689 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3690 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
3691 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
3692 /* Blit without scaling. */
3693 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3694 surf_offscreen_dest64, &dst_rect64, D3DTEXF_NONE);
3695 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3696 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3697 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy,
3698 surf_offscreen_dest64, &dst_rect64, D3DTEXF_NONE);
3699 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3700 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3701 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3702 surf_offscreen_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3703 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3705 /* offscreenplain ==> rendertarget texture, same size. */
3706 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3707 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3708 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3709 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3710 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3711 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3712 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
3713 /* Blit without scaling. */
3714 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3715 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3716 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3717 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3718 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy,
3719 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3720 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3721 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3722 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3723 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3724 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3726 /* offscreenplain ==> rendertarget surface, same size. */
3727 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3728 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3729 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3730 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
3731 /* Blit without scaling. */
3732 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3733 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3734 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3735 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3736 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy,
3737 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3738 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3739 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3740 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3741 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3742 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3744 /* offscreenplain ==> texture, same size (should fail). */
3745 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3746 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3748 /* Fill the smaller offscreen surface with red. */
3749 fill_surface(surf_offscreen32, 0xffff0000, 0);
3751 /* offscreenplain ==> offscreenplain, scaling (should fail). */
3752 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3753 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3755 /* offscreenplain ==> rendertarget texture, scaling. */
3756 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3757 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3758 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3759 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3760 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3761 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3762 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3764 /* offscreenplain ==> rendertarget surface, scaling. */
3765 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3766 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3767 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3768 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3770 /* offscreenplain ==> texture, scaling (should fail). */
3771 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3772 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3774 /*************************************************************
3775 * Tests for when the source parameter is a regular texture. *
3776 *************************************************************/
3778 /* Fill the surface of the regular texture with blue. */
3779 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT. */
3780 fill_surface(surf_temp64, 0xff0000ff, 0);
3781 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
3782 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3784 /* texture ==> offscreenplain, same size. */
3785 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3786 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3788 /* texture ==> rendertarget texture, same size. */
3789 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3790 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3791 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3792 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3793 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3794 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3795 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
3796 /* Blit without scaling. */
3797 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3798 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3799 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3800 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3801 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy,
3802 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3803 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3804 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3805 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3806 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3807 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3809 /* texture ==> rendertarget surface, same size. */
3810 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3811 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3812 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3813 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
3814 /* Blit without scaling. */
3815 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3816 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3817 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3818 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3819 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy,
3820 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3821 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3822 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3823 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3824 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3825 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3827 /* texture ==> texture, same size (should fail). */
3828 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3829 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3831 /* Fill the surface of the smaller regular texture with red. */
3832 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT. */
3833 fill_surface(surf_temp32, 0xffff0000, 0);
3834 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
3835 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3837 /* texture ==> offscreenplain, scaling (should fail). */
3838 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3839 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3841 /* texture ==> rendertarget texture, scaling. */
3842 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3843 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3844 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3845 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3846 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3847 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3848 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3850 /* texture ==> rendertarget surface, scaling. */
3851 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3852 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3853 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3854 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3856 /* texture ==> texture, scaling (should fail). */
3857 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3858 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3860 /******************************************************************
3861 * Tests for when the source parameter is a rendertarget texture. *
3862 ******************************************************************/
3864 /* Fill the surface of the rendertarget texture with white. */
3865 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT. */
3866 fill_surface(surf_temp64, 0xffffffff, 0);
3867 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
3868 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3870 /* rendertarget texture ==> offscreenplain, same size. */
3871 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3872 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3874 /* rendertarget texture ==> rendertarget texture, same size. */
3875 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3876 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3877 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3878 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3879 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3880 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3881 ok(color == 0xffffffff, "Got unexpected color 0x%08x.\n", color);
3882 /* Blit without scaling. */
3883 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3884 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3885 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3886 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3887 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy,
3888 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3889 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3890 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3891 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3892 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3893 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3895 /* rendertarget texture ==> rendertarget surface, same size. */
3896 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3897 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3898 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3899 ok(color == 0xffffffff, "Got unexpected color 0x%08x.\n", color);
3900 /* Blit without scaling. */
3901 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3902 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3903 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3904 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3905 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy,
3906 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3907 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3908 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3909 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3910 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3911 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3913 /* rendertarget texture ==> texture, same size (should fail). */
3914 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3915 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3917 /* Fill the surface of the smaller rendertarget texture with red. */
3918 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT. */
3919 fill_surface(surf_temp32, 0xffff0000, 0);
3920 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
3921 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3923 /* rendertarget texture ==> offscreenplain, scaling (should fail). */
3924 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3925 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3927 /* rendertarget texture ==> rendertarget texture, scaling. */
3928 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3929 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3930 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3931 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3932 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3933 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3934 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3936 /* rendertarget texture ==> rendertarget surface, scaling. */
3937 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3938 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3939 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3940 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3942 /* rendertarget texture ==> texture, scaling (should fail). */
3943 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3944 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3946 /******************************************************************
3947 * Tests for when the source parameter is a rendertarget surface. *
3948 ******************************************************************/
3950 /* Fill the surface of the rendertarget surface with black. */
3951 fill_surface(surf_rt64, 0xff000000, 0);
3953 /* rendertarget texture ==> offscreenplain, same size. */
3954 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3955 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3957 /* rendertarget surface ==> rendertarget texture, same size. */
3958 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3959 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3960 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3961 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3962 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3963 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3964 ok(color == 0xff000000, "Got unexpected color 0x%08x.\n", color);
3965 /* Blit without scaling. */
3966 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3967 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3968 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3969 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3970 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy,
3971 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3972 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3973 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3974 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3975 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3976 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3978 /* rendertarget surface ==> rendertarget surface, same size. */
3979 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3980 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3981 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3982 ok(color == 0xff000000, "Got unexpected color 0x%08x.\n", color);
3983 /* Blit without scaling. */
3984 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3985 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3986 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3987 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3988 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy,
3989 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3990 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3991 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3992 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3993 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3994 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3996 /* rendertarget surface ==> texture, same size (should fail). */
3997 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3998 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4000 /* Fill the surface of the smaller rendertarget texture with red. */
4001 fill_surface(surf_rt32, 0xffff0000, 0);
4003 /* rendertarget surface ==> offscreenplain, scaling (should fail). */
4004 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
4005 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4007 /* rendertarget surface ==> rendertarget texture, scaling. */
4008 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
4009 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4010 /* We can't lock rendertarget textures, so copy to our temp surface first. */
4011 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
4012 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
4013 color = getPixelColorFromSurface(surf_temp64, 48, 48);
4014 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
4016 /* rendertarget surface ==> rendertarget surface, scaling. */
4017 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
4018 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4019 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
4020 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
4022 /* rendertarget surface ==> texture, scaling (should fail). */
4023 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
4024 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4026 /* backbuffer ==> surface tests (no scaling). */
4027 /* Blit with NULL rectangles. */
4028 hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, D3DTEXF_NONE);
4029 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4030 /* Blit without scaling. */
4031 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect,
4032 surf_tex_rt_dest640_480, &dst_rect, D3DTEXF_NONE);
4033 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4034 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
4035 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy,
4036 surf_tex_rt_dest640_480, &dst_rect, D3DTEXF_NONE);
4037 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4038 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
4039 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect,
4040 surf_tex_rt_dest640_480, &dst_rect_flipy, D3DTEXF_NONE);
4041 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4043 /* TODO: Test format conversions. */
4045 IDirect3DSurface9_Release(backbuffer);
4046 IDirect3DSurface9_Release(surf_rt32);
4047 IDirect3DSurface9_Release(surf_rt64);
4048 IDirect3DSurface9_Release(surf_rt_dest64);
4049 IDirect3DSurface9_Release(surf_temp32);
4050 IDirect3DSurface9_Release(surf_temp64);
4051 IDirect3DSurface9_Release(surf_offscreen32);
4052 IDirect3DSurface9_Release(surf_offscreen64);
4053 IDirect3DSurface9_Release(surf_offscreen_dest64);
4054 IDirect3DSurface9_Release(surf_tex_rt32);
4055 IDirect3DTexture9_Release(tex_rt32);
4056 IDirect3DSurface9_Release(surf_tex_rt64);
4057 IDirect3DTexture9_Release(tex_rt64);
4058 IDirect3DSurface9_Release(surf_tex_rt_dest64);
4059 IDirect3DTexture9_Release(tex_rt_dest64);
4060 IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
4061 IDirect3DTexture9_Release(tex_rt_dest640_480);
4062 IDirect3DSurface9_Release(surf_tex32);
4063 IDirect3DTexture9_Release(tex32);
4064 IDirect3DSurface9_Release(surf_tex64);
4065 IDirect3DTexture9_Release(tex64);
4066 IDirect3DSurface9_Release(surf_tex_dest64);
4067 IDirect3DTexture9_Release(tex_dest64);
4068 refcount = IDirect3DDevice9_Release(device);
4069 ok(!refcount, "Device has %u references left.\n", refcount);
4070 done:
4071 IDirect3D9_Release(d3d);
4072 DestroyWindow(window);
4075 static void maxmip_test(void)
4077 IDirect3DTexture9 *texture;
4078 IDirect3DSurface9 *surface;
4079 IDirect3DDevice9 *device;
4080 IDirect3D9 *d3d;
4081 D3DCOLOR color;
4082 ULONG refcount;
4083 D3DCAPS9 caps;
4084 HWND window;
4085 HRESULT hr;
4086 DWORD ret;
4088 static const struct
4090 struct
4092 float x, y, z;
4093 float s, t;
4095 v[4];
4097 quads[] =
4100 {-1.0, -1.0, 0.0, 0.0, 0.0},
4101 {-1.0, 0.0, 0.0, 0.0, 1.0},
4102 { 0.0, -1.0, 0.0, 1.0, 0.0},
4103 { 0.0, 0.0, 0.0, 1.0, 1.0},
4106 { 0.0, -1.0, 0.0, 0.0, 0.0},
4107 { 0.0, 0.0, 0.0, 0.0, 1.0},
4108 { 1.0, -1.0, 0.0, 1.0, 0.0},
4109 { 1.0, 0.0, 0.0, 1.0, 1.0},
4112 { 0.0, 0.0, 0.0, 0.0, 0.0},
4113 { 0.0, 1.0, 0.0, 0.0, 1.0},
4114 { 1.0, 0.0, 0.0, 1.0, 0.0},
4115 { 1.0, 1.0, 0.0, 1.0, 1.0},
4118 {-1.0, 0.0, 0.0, 0.0, 0.0},
4119 {-1.0, 1.0, 0.0, 0.0, 1.0},
4120 { 0.0, 0.0, 0.0, 1.0, 0.0},
4121 { 0.0, 1.0, 0.0, 1.0, 1.0},
4125 window = create_window();
4126 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4127 ok(!!d3d, "Failed to create a D3D object.\n");
4128 if (!(device = create_device(d3d, window, window, TRUE)))
4130 skip("Failed to create a D3D device, skipping tests.\n");
4131 goto done;
4134 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4135 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4136 if (!(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP))
4138 skip("No mipmap support, skipping tests.\n");
4139 IDirect3DDevice9_Release(device);
4140 goto done;
4143 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0,
4144 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
4145 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
4147 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4148 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
4149 fill_surface(surface, 0xffff0000, 0);
4150 IDirect3DSurface9_Release(surface);
4151 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
4152 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
4153 fill_surface(surface, 0xff00ff00, 0);
4154 IDirect3DSurface9_Release(surface);
4155 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
4156 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
4157 fill_surface(surface, 0xff0000ff, 0);
4158 IDirect3DSurface9_Release(surface);
4160 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4161 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4162 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4163 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4165 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4166 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4167 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4168 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4170 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
4171 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4173 hr = IDirect3DDevice9_BeginScene(device);
4174 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4176 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
4177 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4178 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
4179 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4181 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
4182 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4183 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
4184 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4186 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4187 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4188 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
4189 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4191 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
4192 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4193 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
4194 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4196 hr = IDirect3DDevice9_EndScene(device);
4197 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4199 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
4200 color = getPixelColor(device, 160, 360);
4201 ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
4202 color = getPixelColor(device, 480, 360);
4203 ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
4204 color = getPixelColor(device, 480, 120);
4205 ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
4206 color = getPixelColor(device, 160, 120);
4207 ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
4208 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4209 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4211 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4212 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4214 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
4215 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4217 hr = IDirect3DDevice9_BeginScene(device);
4218 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4220 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
4221 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4222 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
4223 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4225 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
4226 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4227 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
4228 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4230 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4231 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4232 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
4233 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4235 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
4236 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4237 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
4238 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4240 hr = IDirect3DDevice9_EndScene(device);
4241 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4243 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
4244 * level 3 (> levels in texture) samples from the highest level in the
4245 * texture (level 2). */
4246 color = getPixelColor(device, 160, 360);
4247 ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
4248 color = getPixelColor(device, 480, 360);
4249 ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
4250 color = getPixelColor(device, 480, 120);
4251 ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
4252 color = getPixelColor(device, 160, 120);
4253 ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
4254 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4255 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4257 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
4258 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4260 hr = IDirect3DDevice9_BeginScene(device);
4261 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4263 /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
4264 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4265 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4266 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
4267 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4268 ret = IDirect3DTexture9_SetLOD(texture, 1);
4269 ok(ret == 0, "Got unexpected LOD %u.\n", ret);
4270 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
4271 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4273 /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
4274 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4275 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4276 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
4277 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4278 ret = IDirect3DTexture9_SetLOD(texture, 2);
4279 ok(ret == 1, "Got unexpected LOD %u.\n", ret);
4280 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
4281 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4283 /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
4284 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4285 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4286 ret = IDirect3DTexture9_SetLOD(texture, 1);
4287 ok(ret == 2, "Got unexpected LOD %u.\n", ret);
4288 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
4289 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4291 /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
4292 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4293 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4294 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4295 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4296 ret = IDirect3DTexture9_SetLOD(texture, 1);
4297 ok(ret == 1, "Got unexpected LOD %u.\n", ret);
4298 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
4299 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4301 hr = IDirect3DDevice9_EndScene(device);
4302 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4304 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
4305 * level 3 (> levels in texture) samples from the highest level in the
4306 * texture (level 2). */
4307 color = getPixelColor(device, 160, 360);
4308 ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
4309 color = getPixelColor(device, 480, 360);
4310 ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
4311 color = getPixelColor(device, 480, 120);
4312 ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
4313 color = getPixelColor(device, 160, 120);
4314 ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
4316 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4317 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4319 IDirect3DTexture9_Release(texture);
4320 refcount = IDirect3DDevice9_Release(device);
4321 ok(!refcount, "Device has %u references left.\n", refcount);
4322 done:
4323 IDirect3D9_Release(d3d);
4324 DestroyWindow(window);
4327 static void release_buffer_test(void)
4329 IDirect3DVertexBuffer9 *vb;
4330 IDirect3DIndexBuffer9 *ib;
4331 IDirect3DDevice9 *device;
4332 IDirect3D9 *d3d;
4333 D3DCOLOR color;
4334 ULONG refcount;
4335 HWND window;
4336 HRESULT hr;
4337 BYTE *data;
4338 LONG ref;
4340 static const short indices[] = {3, 4, 5};
4341 static const struct
4343 struct vec3 position;
4344 DWORD diffuse;
4346 quad[] =
4348 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
4349 {{-1.0f, 1.0f, 0.1f}, 0xffff0000},
4350 {{ 1.0f, 1.0f, 0.1f}, 0xffff0000},
4352 {{-1.0f, -1.0f, 0.1f}, 0xff00ff00},
4353 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
4354 {{ 1.0f, 1.0f, 0.1f}, 0xff00ff00},
4357 window = create_window();
4358 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4359 ok(!!d3d, "Failed to create a D3D object.\n");
4360 if (!(device = create_device(d3d, window, window, TRUE)))
4362 skip("Failed to create a D3D device, skipping tests.\n");
4363 goto done;
4366 /* Index and vertex buffers should always be creatable */
4367 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0,
4368 D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &vb, NULL);
4369 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
4370 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
4371 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
4372 memcpy(data, quad, sizeof(quad));
4373 hr = IDirect3DVertexBuffer9_Unlock(vb);
4374 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
4376 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0,
4377 D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
4378 ok(SUCCEEDED(hr), "Failed to create index buffer, hr %#x.\n", hr);
4379 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
4380 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
4381 memcpy(data, indices, sizeof(indices));
4382 hr = IDirect3DIndexBuffer9_Unlock(ib);
4383 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
4385 hr = IDirect3DDevice9_SetIndices(device, ib);
4386 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
4387 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
4388 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
4389 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
4390 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4391 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4392 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4394 /* Now destroy the bound index buffer and draw again */
4395 ref = IDirect3DIndexBuffer9_Release(ib);
4396 ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
4398 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4399 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
4401 hr = IDirect3DDevice9_BeginScene(device);
4402 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4403 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent
4404 * D3D from making assumptions about the indices or vertices. */
4405 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
4406 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4407 hr = IDirect3DDevice9_EndScene(device);
4408 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4410 color = getPixelColor(device, 160, 120);
4411 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1), "Got unexpected color 0x%08x.\n", color);
4412 color = getPixelColor(device, 480, 360);
4413 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1), "Got unexpected color 0x%08x.\n", color);
4415 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4416 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4418 /* Index buffer was already destroyed as part of the test */
4419 IDirect3DVertexBuffer9_Release(vb);
4420 refcount = IDirect3DDevice9_Release(device);
4421 ok(!refcount, "Device has %u references left.\n", refcount);
4422 done:
4423 IDirect3D9_Release(d3d);
4424 DestroyWindow(window);
4427 static void float_texture_test(void)
4429 IDirect3DTexture9 *texture;
4430 IDirect3DDevice9 *device;
4431 D3DLOCKED_RECT lr;
4432 IDirect3D9 *d3d;
4433 ULONG refcount;
4434 float *data;
4435 DWORD color;
4436 HWND window;
4437 HRESULT hr;
4439 static const float quad[] =
4441 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
4442 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
4443 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
4444 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4447 window = create_window();
4448 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4449 ok(!!d3d, "Failed to create a D3D object.\n");
4450 if (!(device = create_device(d3d, window, window, TRUE)))
4452 skip("Failed to create a D3D device, skipping tests.\n");
4453 goto done;
4456 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
4457 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK)
4459 skip("D3DFMT_R32F textures not supported\n");
4460 IDirect3DDevice9_Release(device);
4461 goto done;
4464 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F, D3DPOOL_MANAGED, &texture, NULL);
4465 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
4467 memset(&lr, 0, sizeof(lr));
4468 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4469 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
4470 data = lr.pBits;
4471 *data = 0.0;
4472 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4473 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
4475 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4476 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4477 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
4478 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4480 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4481 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
4483 hr = IDirect3DDevice9_BeginScene(device);
4484 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4485 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4486 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4487 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4488 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4489 hr = IDirect3DDevice9_EndScene(device);
4490 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4492 color = getPixelColor(device, 240, 320);
4493 ok(color == 0x0000ffff, "R32F with value 0.0 has color %08x, expected 0x0000ffff\n", color);
4495 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4496 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4498 IDirect3DTexture9_Release(texture);
4499 refcount = IDirect3DDevice9_Release(device);
4500 ok(!refcount, "Device has %u references left.\n", refcount);
4501 done:
4502 IDirect3D9_Release(d3d);
4503 DestroyWindow(window);
4506 static void g16r16_texture_test(void)
4508 IDirect3DTexture9 *texture;
4509 IDirect3DDevice9 *device;
4510 D3DLOCKED_RECT lr;
4511 IDirect3D9 *d3d;
4512 ULONG refcount;
4513 DWORD *data;
4514 DWORD color;
4515 HWND window;
4516 HRESULT hr;
4518 static const float quad[] =
4520 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
4521 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
4522 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
4523 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4526 window = create_window();
4527 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4528 ok(!!d3d, "Failed to create a D3D object.\n");
4529 if (!(device = create_device(d3d, window, window, TRUE)))
4531 skip("Failed to create a D3D device, skipping tests.\n");
4532 goto done;
4535 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
4536 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK)
4538 skip("D3DFMT_G16R16 textures not supported\n");
4539 IDirect3DDevice9_Release(device);
4540 goto done;
4543 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16, D3DPOOL_MANAGED, &texture, NULL);
4544 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
4546 memset(&lr, 0, sizeof(lr));
4547 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4548 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
4549 data = lr.pBits;
4550 *data = 0x0f00f000;
4551 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4552 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
4554 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4555 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4556 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
4557 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4559 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4560 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
4562 hr = IDirect3DDevice9_BeginScene(device);
4563 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4564 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4565 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4566 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4567 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4568 hr = IDirect3DDevice9_EndScene(device);
4569 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4571 color = getPixelColor(device, 240, 320);
4572 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
4573 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
4575 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4576 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4578 IDirect3DTexture9_Release(texture);
4579 refcount = IDirect3DDevice9_Release(device);
4580 ok(!refcount, "Device has %u references left.\n", refcount);
4581 done:
4582 IDirect3D9_Release(d3d);
4583 DestroyWindow(window);
4586 static void check_rect(IDirect3DDevice9 *device, RECT r, const char *message)
4588 LONG x_coords[2][2] =
4590 {r.left - 1, r.left + 1},
4591 {r.right + 1, r.right - 1},
4593 LONG y_coords[2][2] =
4595 {r.top - 1, r.top + 1},
4596 {r.bottom + 1, r.bottom - 1}
4598 unsigned int i, j, x_side, y_side;
4600 for (i = 0; i < 2; ++i)
4602 for (j = 0; j < 2; ++j)
4604 for (x_side = 0; x_side < 2; ++x_side)
4606 for (y_side = 0; y_side < 2; ++y_side)
4608 unsigned int x = x_coords[i][x_side], y = y_coords[j][y_side];
4609 DWORD color;
4610 DWORD expected = (x_side == 1 && y_side == 1) ? 0x00ffffff : 0;
4612 color = getPixelColor(device, x, y);
4613 ok(color == expected, "%s: Pixel (%d, %d) has color %08x, expected %08x\n",
4614 message, x, y, color, expected);
4621 struct projected_textures_test_run
4623 const char *message;
4624 DWORD flags;
4625 IDirect3DVertexDeclaration9 *decl;
4626 BOOL vs, ps;
4627 RECT rect;
4630 static void projected_textures_test(IDirect3DDevice9 *device,
4631 struct projected_textures_test_run tests[4])
4633 unsigned int i;
4635 static const DWORD vertex_shader[] =
4637 0xfffe0101, /* vs_1_1 */
4638 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4639 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
4640 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4641 0x00000001, 0xe00f0000, 0x90e40001, /* mov oT0, v1 */
4642 0x0000ffff /* end */
4644 static const DWORD pixel_shader[] =
4646 0xffff0103, /* ps_1_3 */
4647 0x00000042, 0xb00f0000, /* tex t0 */
4648 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4649 0x0000ffff /* end */
4651 IDirect3DVertexShader9 *vs = NULL;
4652 IDirect3DPixelShader9 *ps = NULL;
4653 IDirect3D9 *d3d;
4654 D3DCAPS9 caps;
4655 HRESULT hr;
4657 IDirect3DDevice9_GetDirect3D(device, &d3d);
4658 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4659 ok(SUCCEEDED(hr), "GetDeviceCaps failed (%08x)\n", hr);
4660 IDirect3D9_Release(d3d);
4662 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
4664 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader, &vs);
4665 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
4667 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 3))
4669 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader, &ps);
4670 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
4673 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0f, 0);
4674 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4676 hr = IDirect3DDevice9_BeginScene(device);
4677 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4679 for (i = 0; i < 4; ++i)
4681 DWORD value = 0xdeadbeef;
4682 static const float proj_quads[] =
4684 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4685 -1.0f, 0.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4686 0.0f, -1.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4687 0.0f, 0.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4689 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4690 0.0f, 0.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4691 1.0f, -1.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4692 1.0f, 0.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4694 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4695 -1.0f, 1.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4696 0.0f, 0.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4697 0.0f, 1.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4699 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4700 0.0f, 1.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4701 1.0f, 0.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4702 1.0f, 1.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4705 if (tests[i].vs)
4707 if (!vs)
4709 skip("Vertex shaders not supported, skipping\n");
4710 continue;
4712 hr = IDirect3DDevice9_SetVertexShader(device, vs);
4714 else
4715 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4716 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
4717 if (tests[i].ps)
4719 if (!ps)
4721 skip("Pixel shaders not supported, skipping\n");
4722 continue;
4724 hr = IDirect3DDevice9_SetPixelShader(device, ps);
4726 else
4727 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4728 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4730 hr = IDirect3DDevice9_SetVertexDeclaration(device, tests[i].decl);
4731 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4733 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, tests[i].flags);
4734 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4735 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, &value);
4736 ok(SUCCEEDED(hr) && value == tests[i].flags,
4737 "GetTextureStageState returned: hr %08x, value %08x.\n", hr, value);
4739 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
4740 &proj_quads[i * 4 * 7], 7 * sizeof(float));
4741 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4744 hr = IDirect3DDevice9_EndScene(device);
4745 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4747 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4748 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4749 if (vs) IDirect3DVertexShader9_Release(vs);
4750 if (ps) IDirect3DPixelShader9_Release(ps);
4752 for (i = 0; i < 4; ++i)
4754 if ((!tests[i].vs || vs) && (!tests[i].ps || ps))
4755 check_rect(device, tests[i].rect, tests[i].message);
4758 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4759 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4762 static void texture_transform_flags_test(void)
4764 HRESULT hr;
4765 IDirect3D9 *d3d;
4766 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
4767 D3DCAPS9 caps;
4768 IDirect3DTexture9 *texture = NULL;
4769 IDirect3DVolumeTexture9 *volume = NULL;
4770 IDirect3DDevice9 *device;
4771 unsigned int x, y, z;
4772 D3DLOCKED_RECT lr;
4773 D3DLOCKED_BOX lb;
4774 D3DCOLOR color;
4775 ULONG refcount;
4776 HWND window;
4777 UINT w, h;
4778 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3, *decl4;
4780 static const D3DVERTEXELEMENT9 decl_elements[] = {
4781 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4782 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4783 D3DDECL_END()
4785 static const D3DVERTEXELEMENT9 decl_elements2[] = {
4786 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4787 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4788 D3DDECL_END()
4790 static const D3DVERTEXELEMENT9 decl_elements3[] = {
4791 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4792 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4793 D3DDECL_END()
4795 static const D3DVERTEXELEMENT9 decl_elements4[] = {
4796 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4797 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4798 D3DDECL_END()
4800 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
4801 0x00, 0xff, 0x00, 0x00,
4802 0x00, 0x00, 0x00, 0x00,
4803 0x00, 0x00, 0x00, 0x00};
4804 static const D3DMATRIX identity =
4806 1.0f, 0.0f, 0.0f, 0.0f,
4807 0.0f, 1.0f, 0.0f, 0.0f,
4808 0.0f, 0.0f, 1.0f, 0.0f,
4809 0.0f, 0.0f, 0.0f, 1.0f,
4810 }}};
4812 window = create_window();
4813 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4814 ok(!!d3d, "Failed to create a D3D object.\n");
4815 if (!(device = create_device(d3d, window, window, TRUE)))
4817 skip("Failed to create a D3D device, skipping tests.\n");
4818 goto done;
4821 memset(&lr, 0, sizeof(lr));
4822 memset(&lb, 0, sizeof(lb));
4823 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
4824 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK)
4825 fmt = D3DFMT_A16B16G16R16;
4827 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4828 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4829 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
4830 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4831 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
4832 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4833 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements4, &decl4);
4834 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4835 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
4836 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
4837 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
4838 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
4839 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
4840 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
4841 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4842 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
4843 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
4844 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
4845 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
4846 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
4847 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
4848 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
4849 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
4850 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState(D3DTSS_COLOROP) returned %08x\n", hr);
4851 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
4852 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState(D3DTSS_COLORARG1) returned %08x\n", hr);
4853 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4854 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
4855 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4856 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4858 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4859 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
4860 w = min(1024, caps.MaxTextureWidth);
4861 h = min(1024, caps.MaxTextureHeight);
4862 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
4863 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
4864 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4865 if (!texture)
4867 skip("Failed to create the test texture.\n");
4868 IDirect3DDevice9_Release(device);
4869 goto done;
4872 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
4873 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
4874 * 1.0 in red and green for the x and y coords
4876 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4877 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
4878 for(y = 0; y < h; y++) {
4879 for(x = 0; x < w; x++) {
4880 double r_f = (double) y / (double) h;
4881 double g_f = (double) x / (double) w;
4882 if(fmt == D3DFMT_A16B16G16R16) {
4883 unsigned short r, g;
4884 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
4885 r = (unsigned short) (r_f * 65536.0);
4886 g = (unsigned short) (g_f * 65536.0);
4887 dst[0] = r;
4888 dst[1] = g;
4889 dst[2] = 0;
4890 dst[3] = 65535;
4891 } else {
4892 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
4893 unsigned char r = (unsigned char) (r_f * 255.0);
4894 unsigned char g = (unsigned char) (g_f * 255.0);
4895 dst[0] = 0;
4896 dst[1] = g;
4897 dst[2] = r;
4898 dst[3] = 255;
4902 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4903 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
4904 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4905 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4907 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4908 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4909 hr = IDirect3DDevice9_BeginScene(device);
4910 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4911 if(SUCCEEDED(hr))
4913 static const float quad1[] =
4915 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f,
4916 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4917 0.0f, -1.0f, 0.1f, 1.0f, 1.0f,
4918 0.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4920 static const float quad2[] =
4922 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4923 -1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4924 0.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4925 0.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4927 static const float quad3[] =
4929 0.0f, 0.0f, 0.1f, 0.5f, 0.5f,
4930 0.0f, 1.0f, 0.1f, 0.5f, 0.5f,
4931 1.0f, 0.0f, 0.1f, 0.5f, 0.5f,
4932 1.0f, 1.0f, 0.1f, 0.5f, 0.5f,
4934 static const float quad4[] =
4936 320.0f, 480.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4937 320.0f, 240.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4938 640.0f, 480.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4939 640.0f, 240.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4941 D3DMATRIX mat =
4943 0.0f, 0.0f, 0.0f, 0.0f,
4944 0.0f, 0.0f, 0.0f, 0.0f,
4945 0.0f, 0.0f, 0.0f, 0.0f,
4946 0.0f, 0.0f, 0.0f, 0.0f,
4947 }}};
4949 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
4950 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4951 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4952 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4953 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4955 /* What happens with transforms enabled? */
4956 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4957 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4958 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4959 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4961 /* What happens if 4 coords are used, but only 2 given ?*/
4962 U(mat).m[2][0] = 1.0f;
4963 U(mat).m[3][1] = 1.0f;
4964 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4965 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4966 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
4967 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4968 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4969 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4971 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
4972 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
4973 * due to the coords in the vertices. (turns out red, indeed)
4975 memset(&mat, 0, sizeof(mat));
4976 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4977 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4978 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
4979 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4980 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4981 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4982 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4983 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4985 hr = IDirect3DDevice9_EndScene(device);
4986 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4988 color = getPixelColor(device, 160, 360);
4989 ok(color_match(color, 0x00ffff00, 1), "quad 1 has color %08x, expected 0x00ffff00\n", color);
4990 color = getPixelColor(device, 160, 120);
4991 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4992 color = getPixelColor(device, 480, 120);
4993 ok(color_match(color, 0x0000ff00, 1), "quad 3 has color %08x, expected 0x0000ff00\n", color);
4994 color = getPixelColor(device, 480, 360);
4995 ok(color_match(color, 0x00ff0000, 1), "quad 4 has color %08x, expected 0x00ff0000\n", color);
4996 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4997 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4999 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
5000 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5002 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5003 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5004 hr = IDirect3DDevice9_BeginScene(device);
5005 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
5006 if(SUCCEEDED(hr))
5008 static const float quad1[] =
5010 -1.0f, -1.0f, 0.1f, 0.8f, 0.2f,
5011 -1.0f, 0.0f, 0.1f, 0.8f, 0.2f,
5012 0.0f, -1.0f, 0.1f, 0.8f, 0.2f,
5013 0.0f, 0.0f, 0.1f, 0.8f, 0.2f,
5015 static const float quad2[] =
5017 -1.0f, 0.0f, 0.1f, 0.5f, 1.0f,
5018 -1.0f, 1.0f, 0.1f, 0.5f, 1.0f,
5019 0.0f, 0.0f, 0.1f, 0.5f, 1.0f,
5020 0.0f, 1.0f, 0.1f, 0.5f, 1.0f,
5022 static const float quad3[] =
5024 0.0f, 0.0f, 0.1f, 0.5f, 1.0f,
5025 0.0f, 1.0f, 0.1f, 0.5f, 1.0f,
5026 1.0f, 0.0f, 0.1f, 0.5f, 1.0f,
5027 1.0f, 1.0f, 0.1f, 0.5f, 1.0f,
5029 static const float quad4[] =
5031 0.0f, -1.0f, 0.1f, 0.8f, 0.2f,
5032 0.0f, 0.0f, 0.1f, 0.8f, 0.2f,
5033 1.0f, -1.0f, 0.1f, 0.8f, 0.2f,
5034 1.0f, 0.0f, 0.1f, 0.8f, 0.2f,
5036 D3DMATRIX mat =
5038 0.0f, 0.0f, 0.0f, 0.0f,
5039 0.0f, 0.0f, 0.0f, 0.0f,
5040 0.0f, 1.0f, 0.0f, 0.0f,
5041 0.0f, 0.0f, 0.0f, 0.0f,
5042 }}};
5044 /* What happens to the default 1 in the 3rd coordinate if it is disabled? */
5045 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5046 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5047 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
5048 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5050 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
5051 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
5053 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
5054 * it behaves like COUNT2 because normal textures require 2 coords. */
5055 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
5056 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5057 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
5058 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
5060 /* Just to be sure, the same as quad2 above */
5061 memset(&mat, 0, sizeof(mat));
5062 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5063 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5064 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
5065 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5066 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
5067 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
5069 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
5070 * used? And what happens to the first? */
5071 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
5072 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5073 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
5074 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
5076 hr = IDirect3DDevice9_EndScene(device);
5077 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
5079 color = getPixelColor(device, 160, 360);
5080 ok(color_match(color, 0x00ff0000, 1), "quad 1 has color %08x, expected 0x00ff0000\n", color);
5081 color = getPixelColor(device, 160, 120);
5082 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
5083 color = getPixelColor(device, 480, 120);
5084 ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
5085 "quad 3 has color %08x, expected 0x00ff8000\n", color);
5086 color = getPixelColor(device, 480, 360);
5087 ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00ff0000, 1),
5088 "quad 4 has color %08x, expected 0x0033cc00\n", color);
5089 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5090 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5092 IDirect3DTexture9_Release(texture);
5094 /* Test projected textures, without any fancy matrices */
5095 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
5096 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5097 if (SUCCEEDED(hr))
5099 struct projected_textures_test_run projected_tests_1[4] =
5102 "D3DTTFF_COUNT4 | D3DTTFF_PROJECTED - bottom left",
5103 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED,
5104 decl3,
5105 FALSE, TRUE,
5106 {120, 300, 240, 390},
5109 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED - bottom right",
5110 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
5111 decl3,
5112 FALSE, TRUE,
5113 {400, 360, 480, 420},
5115 /* Try with some invalid values */
5117 "0xffffffff (draws like COUNT4 | PROJECTED) - top left",
5118 0xffffffff,
5119 decl3,
5120 FALSE, TRUE,
5121 {120, 60, 240, 150}
5124 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (draws non-projected) - top right",
5125 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
5126 decl4,
5127 FALSE, TRUE,
5128 {340, 210, 360, 225},
5131 struct projected_textures_test_run projected_tests_2[4] =
5134 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED, texcoord has 4 components) - bottom left",
5135 D3DTTFF_PROJECTED,
5136 decl3,
5137 FALSE, TRUE,
5138 {120, 300, 240, 390},
5141 "D3DTTFF_PROJECTED (like COUNT3 | PROJECTED, texcoord has only 3 components) - bottom right",
5142 D3DTTFF_PROJECTED,
5143 decl,
5144 FALSE, TRUE,
5145 {400, 360, 480, 420},
5148 "0xffffffff (like COUNT3 | PROJECTED, texcoord has only 3 components) - top left",
5149 0xffffffff,
5150 decl,
5151 FALSE, TRUE,
5152 {80, 120, 160, 180},
5155 "D3DTTFF_COUNT1 (draws non-projected) - top right",
5156 D3DTTFF_COUNT1,
5157 decl4,
5158 FALSE, TRUE,
5159 {340, 210, 360, 225},
5162 struct projected_textures_test_run projected_tests_3[4] =
5165 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom left",
5166 D3DTTFF_PROJECTED,
5167 decl3,
5168 TRUE, FALSE,
5169 {120, 300, 240, 390},
5172 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom right",
5173 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
5174 decl3,
5175 TRUE, TRUE,
5176 {440, 300, 560, 390},
5179 "0xffffffff (like COUNT4 | PROJECTED) - top left",
5180 0xffffffff,
5181 decl3,
5182 TRUE, TRUE,
5183 {120, 60, 240, 150},
5186 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - top right",
5187 D3DTTFF_PROJECTED,
5188 decl3,
5189 FALSE, FALSE,
5190 {440, 60, 560, 150},
5194 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
5195 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5197 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5198 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
5199 for(x = 0; x < 4; x++) {
5200 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
5202 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5203 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
5204 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5205 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
5207 projected_textures_test(device, projected_tests_1);
5208 projected_textures_test(device, projected_tests_2);
5209 projected_textures_test(device, projected_tests_3);
5211 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5212 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
5213 IDirect3DTexture9_Release(texture);
5216 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
5217 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5218 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
5219 * Thus watch out if sampling from texels between 0 and 1.
5221 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
5222 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
5223 "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
5224 if(!volume) {
5225 skip("Failed to create a volume texture\n");
5226 goto out;
5229 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
5230 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
5231 for(z = 0; z < 32; z++) {
5232 for(y = 0; y < 32; y++) {
5233 for(x = 0; x < 32; x++) {
5234 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
5235 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
5236 float r_f = (float) x / 31.0;
5237 float g_f = (float) y / 31.0;
5238 float b_f = (float) z / 31.0;
5240 if(fmt == D3DFMT_A16B16G16R16) {
5241 unsigned short *mem_s = mem;
5242 mem_s[0] = r_f * 65535.0;
5243 mem_s[1] = g_f * 65535.0;
5244 mem_s[2] = b_f * 65535.0;
5245 mem_s[3] = 65535;
5246 } else {
5247 unsigned char *mem_c = mem;
5248 mem_c[0] = b_f * 255.0;
5249 mem_c[1] = g_f * 255.0;
5250 mem_c[2] = r_f * 255.0;
5251 mem_c[3] = 255;
5256 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
5257 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
5259 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
5260 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
5262 hr = IDirect3DDevice9_BeginScene(device);
5263 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
5264 if(SUCCEEDED(hr))
5266 static const float quad1[] =
5268 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5269 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5270 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5271 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5273 static const float quad2[] =
5275 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5276 -1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5277 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5278 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5280 static const float quad3[] =
5282 0.0f, 0.0f, 0.1f, 0.0f, 0.0f,
5283 0.0f, 1.0f, 0.1f, 0.0f, 0.0f,
5284 1.0f, 0.0f, 0.1f, 0.0f, 0.0f,
5285 1.0f, 1.0f, 0.1f, 0.0f, 0.0f,
5287 static const float quad4[] =
5289 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5290 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5291 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5292 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5294 D3DMATRIX mat =
5296 1.0f, 0.0f, 0.0f, 0.0f,
5297 0.0f, 0.0f, 1.0f, 0.0f,
5298 0.0f, 1.0f, 0.0f, 0.0f,
5299 0.0f, 0.0f, 0.0f, 1.0f,
5300 }}};
5301 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5302 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5304 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
5305 * values
5307 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5308 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5309 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
5310 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5311 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5312 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5314 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
5315 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
5316 * otherwise the w will be missing(blue).
5317 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
5318 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3. */
5319 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
5320 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5321 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5322 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5324 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
5325 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
5326 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5327 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
5328 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5329 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5330 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5331 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
5332 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5334 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
5335 * disable. ATI extends it up to the amount of values needed for the volume texture
5337 memset(&mat, 0, sizeof(mat));
5338 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5339 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5340 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
5341 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5342 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5343 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5344 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5345 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5347 hr = IDirect3DDevice9_EndScene(device);
5348 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
5351 color = getPixelColor(device, 160, 360);
5352 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
5353 color = getPixelColor(device, 160, 120);
5354 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
5355 "quad 2 has color %08x, expected 0x00ffff00\n", color);
5356 color = getPixelColor(device, 480, 120);
5357 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
5358 color = getPixelColor(device, 480, 360);
5359 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
5361 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5362 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5364 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
5365 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5366 hr = IDirect3DDevice9_BeginScene(device);
5367 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
5368 if(SUCCEEDED(hr))
5370 static const float quad1[] =
5372 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5373 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5374 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5375 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5377 static const float quad2[] =
5379 -1.0f, 0.0f, 0.1f,
5380 -1.0f, 1.0f, 0.1f,
5381 0.0f, 0.0f, 0.1f,
5382 0.0f, 1.0f, 0.1f,
5384 static const float quad3[] =
5386 0.0f, 0.0f, 0.1f, 1.0f,
5387 0.0f, 1.0f, 0.1f, 1.0f,
5388 1.0f, 0.0f, 0.1f, 1.0f,
5389 1.0f, 1.0f, 0.1f, 1.0f,
5391 static const D3DMATRIX mat =
5393 0.0f, 0.0f, 0.0f, 0.0f,
5394 0.0f, 0.0f, 0.0f, 0.0f,
5395 0.0f, 0.0f, 0.0f, 0.0f,
5396 0.0f, 1.0f, 0.0f, 0.0f,
5397 }}};
5398 static const D3DMATRIX mat2 =
5400 0.0f, 0.0f, 0.0f, 1.0f,
5401 1.0f, 0.0f, 0.0f, 0.0f,
5402 0.0f, 1.0f, 0.0f, 0.0f,
5403 0.0f, 0.0f, 1.0f, 0.0f,
5404 }}};
5405 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5406 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5408 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
5409 * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
5410 * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
5411 * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
5412 * 4th *input* coordinate.
5414 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5415 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5416 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
5417 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5418 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5419 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5421 /* None passed */
5422 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
5423 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5424 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5425 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5426 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5427 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5429 /* 4 used, 1 passed */
5430 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5431 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5432 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat2);
5433 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5434 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
5435 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5437 hr = IDirect3DDevice9_EndScene(device);
5438 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
5440 color = getPixelColor(device, 160, 360);
5441 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
5442 color = getPixelColor(device, 160, 120);
5443 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
5444 color = getPixelColor(device, 480, 120);
5445 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
5446 /* Quad4: unused */
5448 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5449 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5451 IDirect3DVolumeTexture9_Release(volume);
5453 out:
5454 IDirect3DVertexDeclaration9_Release(decl);
5455 IDirect3DVertexDeclaration9_Release(decl2);
5456 IDirect3DVertexDeclaration9_Release(decl3);
5457 IDirect3DVertexDeclaration9_Release(decl4);
5458 refcount = IDirect3DDevice9_Release(device);
5459 ok(!refcount, "Device has %u references left.\n", refcount);
5460 done:
5461 IDirect3D9_Release(d3d);
5462 DestroyWindow(window);
5465 static void texdepth_test(void)
5467 IDirect3DPixelShader9 *shader;
5468 IDirect3DDevice9 *device;
5469 IDirect3D9 *d3d;
5470 ULONG refcount;
5471 D3DCAPS9 caps;
5472 DWORD color;
5473 HWND window;
5474 HRESULT hr;
5476 static const float texdepth_test_data1[] = { 0.25f, 2.0f, 0.0f, 0.0f};
5477 static const float texdepth_test_data2[] = { 0.25f, 0.5f, 0.0f, 0.0f};
5478 static const float texdepth_test_data3[] = {-1.00f, 0.1f, 0.0f, 0.0f};
5479 static const float texdepth_test_data4[] = {-0.25f, -0.5f, 0.0f, 0.0f};
5480 static const float texdepth_test_data5[] = { 1.00f, -0.1f, 0.0f, 0.0f};
5481 static const float texdepth_test_data6[] = { 1.00f, 0.5f, 0.0f, 0.0f};
5482 static const float texdepth_test_data7[] = { 0.50f, 0.0f, 0.0f, 0.0f};
5483 static const DWORD shader_code[] =
5485 0xffff0104, /* ps_1_4 */
5486 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
5487 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
5488 0x0000fffd, /* phase */
5489 0x00000057, 0x800f0005, /* texdepth r5 */
5490 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
5491 0x0000ffff /* end */
5493 static const float vertex[] =
5495 -1.0f, -1.0f, 0.0f,
5496 -1.0f, 1.0f, 0.0f,
5497 1.0f, -1.0f, 1.0f,
5498 1.0f, 1.0f, 1.0f,
5501 window = create_window();
5502 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5503 ok(!!d3d, "Failed to create a D3D object.\n");
5504 if (!(device = create_device(d3d, window, window, TRUE)))
5506 skip("Failed to create a D3D device, skipping tests.\n");
5507 goto done;
5510 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5511 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5512 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
5514 skip("No ps_1_4 support, skipping tests.\n");
5515 IDirect3DDevice9_Release(device);
5516 goto done;
5519 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5520 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5522 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
5523 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5524 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5525 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
5526 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
5527 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5528 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
5529 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5530 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
5531 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5532 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5533 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
5535 /* Fill the depth buffer with a gradient */
5536 hr = IDirect3DDevice9_BeginScene(device);
5537 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5538 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5539 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5540 hr = IDirect3DDevice9_EndScene(device);
5541 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5543 /* Now perform the actual tests. Same geometry, but with the shader */
5544 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
5545 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5546 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
5547 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5548 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5549 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5551 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
5552 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5553 hr = IDirect3DDevice9_BeginScene(device);
5554 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5555 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5556 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5557 hr = IDirect3DDevice9_EndScene(device);
5558 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5560 color = getPixelColor(device, 158, 240);
5561 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
5562 color = getPixelColor(device, 162, 240);
5563 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
5565 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5566 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5568 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5569 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5571 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
5572 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5573 hr = IDirect3DDevice9_BeginScene(device);
5574 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5575 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5576 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5577 hr = IDirect3DDevice9_EndScene(device);
5578 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5580 color = getPixelColor(device, 318, 240);
5581 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
5582 color = getPixelColor(device, 322, 240);
5583 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
5585 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5586 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5588 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
5589 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5591 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
5592 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5593 hr = IDirect3DDevice9_BeginScene(device);
5594 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5595 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5596 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5597 hr = IDirect3DDevice9_EndScene(device);
5598 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5600 color = getPixelColor(device, 1, 240);
5601 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
5603 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5604 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5606 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
5607 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5609 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
5610 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5611 hr = IDirect3DDevice9_BeginScene(device);
5612 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5613 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5614 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5615 hr = IDirect3DDevice9_EndScene(device);
5616 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5618 color = getPixelColor(device, 318, 240);
5619 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
5620 color = getPixelColor(device, 322, 240);
5621 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
5623 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5624 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5626 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5627 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5629 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
5630 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5631 hr = IDirect3DDevice9_BeginScene(device);
5632 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5633 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5634 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5635 hr = IDirect3DDevice9_EndScene(device);
5636 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5638 color = getPixelColor(device, 1, 240);
5639 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
5641 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5642 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5644 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
5645 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5647 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
5648 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5649 hr = IDirect3DDevice9_BeginScene(device);
5650 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5651 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5652 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5653 hr = IDirect3DDevice9_EndScene(device);
5654 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5656 color = getPixelColor(device, 638, 240);
5657 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
5659 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5660 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5662 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
5663 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5665 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
5666 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5667 hr = IDirect3DDevice9_BeginScene(device);
5668 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5669 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5670 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5671 hr = IDirect3DDevice9_EndScene(device);
5672 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5674 color = getPixelColor(device, 638, 240);
5675 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
5677 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5678 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5680 IDirect3DPixelShader9_Release(shader);
5681 refcount = IDirect3DDevice9_Release(device);
5682 ok(!refcount, "Device has %u references left.\n", refcount);
5683 done:
5684 IDirect3D9_Release(d3d);
5685 DestroyWindow(window);
5688 static void texkill_test(void)
5690 IDirect3DPixelShader9 *shader;
5691 IDirect3DDevice9 *device;
5692 IDirect3D9 *d3d;
5693 ULONG refcount;
5694 D3DCAPS9 caps;
5695 DWORD color;
5696 HWND window;
5697 HRESULT hr;
5699 static const float vertex[] =
5701 /* bottom top right left */
5702 -1.0f, -1.0f, 1.0f, -0.1f, 0.9f, 0.9f, -0.1f,
5703 -1.0f, 1.0f, 1.0f, -0.1f, 0.9f, -0.1f, 0.9f,
5704 1.0f, -1.0f, 0.0f, 0.9f, -0.1f, 0.9f, -0.1f,
5705 1.0f, 1.0f, 0.0f, 0.9f, -0.1f, -0.1f, 0.9f,
5707 static const DWORD shader_code_11[] =
5709 0xffff0101, /* ps_1_1 */
5710 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
5711 0x00000041, 0xb00f0000, /* texkill t0 */
5712 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5713 0x0000ffff /* end */
5715 static const DWORD shader_code_20[] =
5717 0xffff0200, /* ps_2_0 */
5718 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
5719 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
5720 0x01000041, 0xb00f0000, /* texkill t0 */
5721 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
5722 0x0000ffff /* end */
5725 window = create_window();
5726 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5727 ok(!!d3d, "Failed to create a D3D object.\n");
5728 if (!(device = create_device(d3d, window, window, TRUE)))
5730 skip("Failed to create a D3D device, skipping tests.\n");
5731 goto done;
5734 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5735 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5736 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
5738 skip("No ps_1_1 support, skipping tests.\n");
5739 IDirect3DDevice9_Release(device);
5740 goto done;
5743 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
5744 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5745 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
5746 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5748 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5749 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5750 hr = IDirect3DDevice9_BeginScene(device);
5751 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5752 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
5753 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5754 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
5755 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5756 hr = IDirect3DDevice9_EndScene(device);
5757 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5759 color = getPixelColor(device, 63, 46);
5760 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
5761 color = getPixelColor(device, 66, 46);
5762 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
5763 color = getPixelColor(device, 63, 49);
5764 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
5765 color = getPixelColor(device, 66, 49);
5766 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
5768 color = getPixelColor(device, 578, 46);
5769 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5770 color = getPixelColor(device, 575, 46);
5771 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5772 color = getPixelColor(device, 578, 49);
5773 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
5774 color = getPixelColor(device, 575, 49);
5775 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5777 color = getPixelColor(device, 63, 430);
5778 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5779 color = getPixelColor(device, 63, 433);
5780 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5781 color = getPixelColor(device, 66, 433);
5782 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
5783 color = getPixelColor(device, 66, 430);
5784 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5786 color = getPixelColor(device, 578, 430);
5787 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5788 color = getPixelColor(device, 578, 433);
5789 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5790 color = getPixelColor(device, 575, 433);
5791 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
5792 color = getPixelColor(device, 575, 430);
5793 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5795 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5796 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5798 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5799 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5800 IDirect3DPixelShader9_Release(shader);
5802 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5803 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5804 if (FAILED(IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader)))
5806 skip("Failed to create 2.0 test shader, most likely not supported.\n");
5807 IDirect3DDevice9_Release(device);
5808 goto done;
5811 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5812 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5813 hr = IDirect3DDevice9_BeginScene(device);
5814 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5815 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
5816 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5817 hr = IDirect3DDevice9_EndScene(device);
5818 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5820 color = getPixelColor(device, 63, 46);
5821 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
5822 color = getPixelColor(device, 66, 46);
5823 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
5824 color = getPixelColor(device, 63, 49);
5825 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
5826 color = getPixelColor(device, 66, 49);
5827 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
5829 color = getPixelColor(device, 578, 46);
5830 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5831 color = getPixelColor(device, 575, 46);
5832 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5833 color = getPixelColor(device, 578, 49);
5834 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5835 color = getPixelColor(device, 575, 49);
5836 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5838 color = getPixelColor(device, 63, 430);
5839 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5840 color = getPixelColor(device, 63, 433);
5841 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5842 color = getPixelColor(device, 66, 433);
5843 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5844 color = getPixelColor(device, 66, 430);
5845 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5847 color = getPixelColor(device, 578, 430);
5848 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5849 color = getPixelColor(device, 578, 433);
5850 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5851 color = getPixelColor(device, 575, 433);
5852 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5853 color = getPixelColor(device, 575, 430);
5854 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5856 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5857 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5859 IDirect3DPixelShader9_Release(shader);
5860 refcount = IDirect3DDevice9_Release(device);
5861 ok(!refcount, "Device has %u references left.\n", refcount);
5862 done:
5863 IDirect3D9_Release(d3d);
5864 DestroyWindow(window);
5867 static void test_mipmap_autogen(void)
5869 IDirect3DSurface9 *surface, *surface2, *surface3, *backbuffer;
5870 IDirect3DTexture9 *texture, *texture2, *texture3;
5871 IDirect3DDevice9 *device;
5872 unsigned int x, y;
5873 D3DLOCKED_RECT lr;
5874 IDirect3D9 *d3d;
5875 D3DCOLOR color;
5876 ULONG refcount;
5877 D3DCAPS9 caps;
5878 HWND window;
5879 HRESULT hr;
5881 static const RECT r1 = {256, 256, 512, 512};
5882 static const RECT r2 = {512, 256, 768, 512};
5883 static const RECT r3 = {256, 512, 512, 768};
5884 static const RECT r4 = {512, 512, 768, 768};
5885 static const float quad[] =
5887 -0.5f, -0.5f, 0.1f, 0.0f, 0.0f,
5888 -0.5f, 0.5f, 0.1f, 0.0f, 1.0f,
5889 0.5f, -0.5f, 0.1f, 1.0f, 0.0f,
5890 0.5f, 0.5f, 0.1f, 1.0f, 1.0f,
5893 window = create_window();
5894 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5895 ok(!!d3d, "Failed to create a D3D object.\n");
5896 if (!(device = create_device(d3d, window, window, TRUE)))
5898 skip("Failed to create a D3D device, skipping tests.\n");
5899 goto done;
5902 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
5903 D3DFMT_X8R8G8B8, D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK)
5905 skip("No autogenmipmap support.\n");
5906 IDirect3DDevice9_Release(device);
5907 goto done;
5910 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
5911 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
5913 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 1.0f, 0);
5914 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5916 /* Make the texture big enough that a mipmap level > 0 is used. */
5917 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
5918 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
5919 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5921 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5922 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
5923 memset(&lr, 0, sizeof(lr));
5924 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5925 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
5926 for(y = 0; y < 1024; y++) {
5927 for(x = 0; x < 1024; x++) {
5928 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
5929 POINT pt;
5931 pt.x = x;
5932 pt.y = y;
5933 if(PtInRect(&r1, pt)) {
5934 *dst = 0xffff0000;
5935 } else if(PtInRect(&r2, pt)) {
5936 *dst = 0xff00ff00;
5937 } else if(PtInRect(&r3, pt)) {
5938 *dst = 0xff0000ff;
5939 } else if(PtInRect(&r4, pt)) {
5940 *dst = 0xff000000;
5941 } else {
5942 *dst = 0xffffffff;
5946 hr = IDirect3DSurface9_UnlockRect(surface);
5947 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
5948 IDirect3DSurface9_Release(surface);
5950 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5951 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5952 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
5953 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
5954 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5955 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
5957 hr = IDirect3DDevice9_BeginScene(device);
5958 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5959 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5960 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5961 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5962 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5963 hr = IDirect3DDevice9_EndScene(device);
5964 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5965 IDirect3DTexture9_Release(texture);
5967 color = getPixelColor(device, 200, 200);
5968 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
5969 color = getPixelColor(device, 280, 200);
5970 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
5971 color = getPixelColor(device, 360, 200);
5972 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
5973 color = getPixelColor(device, 440, 200);
5974 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5975 color = getPixelColor(device, 200, 270);
5976 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
5977 color = getPixelColor(device, 280, 270);
5978 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
5979 color = getPixelColor(device, 360, 270);
5980 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
5981 color = getPixelColor(device, 440, 270);
5982 ok(color == 0x00ffffff, "pixel 440/270 has color %08x, expected 0x00ffffff\n", color);
5983 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5984 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5986 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5987 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5988 if (!(caps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES))
5990 skip("Blitting from textures is not supported.\n");
5991 IDirect3DSurface9_Release(backbuffer);
5992 IDirect3DDevice9_Release(device);
5993 goto done;
5995 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1, 0,
5996 D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, 0);
5997 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5998 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
5999 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture2, 0);
6000 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
6001 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP | D3DUSAGE_RENDERTARGET,
6002 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture3, 0);
6003 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
6005 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6006 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x.\n", hr);
6007 memset(&lr, 0, sizeof(lr));
6008 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
6009 ok(SUCCEEDED(hr), "Failed to map surface, hr %#x.\n", hr);
6010 for (y = 0; y < 1024; ++y)
6012 for (x = 0; x < 1024; ++x)
6014 DWORD *dst = (DWORD *)((BYTE *)lr.pBits + y * lr.Pitch + x * 4);
6015 POINT pt;
6017 pt.x = x;
6018 pt.y = y;
6019 if (PtInRect(&r1, pt))
6020 *dst = 0xffff0000;
6021 else if (PtInRect(&r2, pt))
6022 *dst = 0xff00ff00;
6023 else if (PtInRect(&r3, pt))
6024 *dst = 0xff0000ff;
6025 else if (PtInRect(&r4, pt))
6026 *dst = 0xff000000;
6027 else
6028 *dst = 0xffffffff;
6031 hr = IDirect3DSurface9_UnlockRect(surface);
6032 ok(SUCCEEDED(hr), "Failed to unmap surface, hr %#x.\n", hr);
6033 IDirect3DSurface9_Release(surface);
6035 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture,
6036 (IDirect3DBaseTexture9 *)texture2);
6037 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
6039 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture2);
6040 ok(SUCCEEDED(hr), "Failed to set texture, hr %x.\n", hr);
6042 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 1.0f, 0);
6043 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6045 hr = IDirect3DDevice9_BeginScene(device);
6046 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6047 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6048 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6049 hr = IDirect3DDevice9_EndScene(device);
6050 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6052 color = getPixelColor(device, 200, 200);
6053 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6054 color = getPixelColor(device, 280, 200);
6055 ok(color == 0x000000ff, "Unexpected color 0x%08x.\n", color);
6056 color = getPixelColor(device, 360, 200);
6057 ok(color == 0x00000000, "Unexpected color 0x%08x.\n", color);
6058 color = getPixelColor(device, 440, 200);
6059 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6060 color = getPixelColor(device, 200, 270);
6061 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6062 color = getPixelColor(device, 280, 270);
6063 ok(color == 0x00ff0000, "Unexpected color 0x%08x.\n", color);
6064 color = getPixelColor(device, 360, 270);
6065 ok(color == 0x0000ff00, "Unexpected color 0x%08x.\n", color);
6066 color = getPixelColor(device, 440, 270);
6067 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6069 hr = IDirect3DTexture9_GetSurfaceLevel(texture2, 0, &surface2);
6070 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x.\n", hr);
6071 hr = IDirect3DTexture9_GetSurfaceLevel(texture3, 0, &surface3);
6072 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x.\n", hr);
6073 hr = IDirect3DDevice9_StretchRect(device, surface2, NULL, surface3, NULL, D3DTEXF_POINT);
6074 ok(SUCCEEDED(hr), "Failed to blit texture, hr %#x.\n", hr);
6076 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture3);
6077 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
6079 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 1.0f, 0);
6080 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6082 hr = IDirect3DDevice9_BeginScene(device);
6083 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6084 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6085 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6086 hr = IDirect3DDevice9_EndScene(device);
6087 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6089 color = getPixelColor(device, 200, 200);
6090 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6091 color = getPixelColor(device, 280, 200);
6092 ok(color == 0x000000ff, "Unexpected color 0x%08x.\n", color);
6093 color = getPixelColor(device, 360, 200);
6094 ok(color == 0x00000000, "Unexpected color 0x%08x.\n", color);
6095 color = getPixelColor(device, 440, 200);
6096 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6097 color = getPixelColor(device, 200, 270);
6098 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6099 color = getPixelColor(device, 280, 270);
6100 ok(color == 0x00ff0000, "Unexpected color 0x%08x.\n", color);
6101 color = getPixelColor(device, 360, 270);
6102 ok(color == 0x0000ff00, "Unexpected color 0x%08x.\n", color);
6103 color = getPixelColor(device, 440, 270);
6104 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6106 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface3);
6107 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
6109 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 1.0f, 0);
6110 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6112 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6113 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
6115 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 1.0f, 0);
6116 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6118 hr = IDirect3DDevice9_BeginScene(device);
6119 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6120 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6121 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, 200, 200);
6126 ok(color == 0x0000ffff, "Unexpected color 0x%08x.\n", color);
6128 IDirect3DSurface9_Release(surface3);
6129 IDirect3DSurface9_Release(surface2);
6130 IDirect3DTexture9_Release(texture3);
6131 IDirect3DTexture9_Release(texture2);
6132 IDirect3DTexture9_Release(texture);
6133 IDirect3DSurface9_Release(backbuffer);
6135 refcount = IDirect3DDevice9_Release(device);
6136 ok(!refcount, "Device has %u references left.\n", refcount);
6137 done:
6138 IDirect3D9_Release(d3d);
6139 DestroyWindow(window);
6142 static void test_constant_clamp_vs(void)
6144 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
6145 IDirect3DVertexDeclaration9 *decl;
6146 IDirect3DDevice9 *device;
6147 IDirect3D9 *d3d;
6148 D3DCOLOR color;
6149 ULONG refcount;
6150 D3DCAPS9 caps;
6151 HWND window;
6152 HRESULT hr;
6154 static const DWORD shader_code_11[] =
6156 0xfffe0101, /* vs_1_1 */
6157 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6158 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6159 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
6160 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6161 0x0000ffff /* end */
6163 static const DWORD shader_code_11_2[] =
6165 0xfffe0101, /* vs_1_1 */
6166 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
6167 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
6168 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6169 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6170 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
6171 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6172 0x0000ffff /* end */
6174 static const DWORD shader_code_20[] =
6176 0xfffe0200, /* vs_2_0 */
6177 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6178 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6179 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
6180 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6181 0x0000ffff /* end */
6183 static const DWORD shader_code_20_2[] =
6185 0xfffe0200, /* vs_2_0 */
6186 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
6187 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
6188 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6189 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6190 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
6191 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6192 0x0000ffff /* end */
6194 static const D3DVERTEXELEMENT9 decl_elements[] =
6196 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6197 D3DDECL_END()
6199 static const float quad1[] =
6201 -1.0f, -1.0f, 0.1f,
6202 -1.0f, 0.0f, 0.1f,
6203 0.0f, -1.0f, 0.1f,
6204 0.0f, 0.0f, 0.1f,
6206 static const float quad2[] =
6208 0.0f, -1.0f, 0.1f,
6209 0.0f, 0.0f, 0.1f,
6210 1.0f, -1.0f, 0.1f,
6211 1.0f, 0.0f, 0.1f,
6213 static const float quad3[] =
6215 0.0f, 0.0f, 0.1f,
6216 0.0f, 1.0f, 0.1f,
6217 1.0f, 0.0f, 0.1f,
6218 1.0f, 1.0f, 0.1f,
6220 static const float quad4[] =
6222 -1.0f, 0.0f, 0.1f,
6223 -1.0f, 1.0f, 0.1f,
6224 0.0f, 0.0f, 0.1f,
6225 0.0f, 1.0f, 0.1f,
6227 static const float test_data_c1[4] = { 1.25f, -0.50f, -1.50f, 1.0f};
6228 static const float test_data_c2[4] = {-0.50f, 1.25f, 2.00f, 1.0f};
6230 window = create_window();
6231 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6232 ok(!!d3d, "Failed to create a D3D object.\n");
6233 if (!(device = create_device(d3d, window, window, TRUE)))
6235 skip("Failed to create a D3D device, skipping tests.\n");
6236 goto done;
6239 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6240 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6241 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
6243 skip("No vs_1_1 support, skipping tests.\n");
6244 IDirect3DDevice9_Release(device);
6245 goto done;
6248 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
6249 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6251 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
6252 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6253 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
6254 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6255 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
6256 if(FAILED(hr)) shader_20 = NULL;
6257 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
6258 if(FAILED(hr)) shader_20_2 = NULL;
6259 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
6260 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6262 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
6263 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
6264 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
6265 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
6266 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6267 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6269 hr = IDirect3DDevice9_BeginScene(device);
6270 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6272 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
6273 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
6274 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
6275 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6277 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
6278 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
6279 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
6280 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6282 if (shader_20)
6284 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
6285 ok(SUCCEEDED(hr), "Failed to set vertex 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);
6290 if (shader_20_2)
6292 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
6293 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
6294 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
6295 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6298 hr = IDirect3DDevice9_EndScene(device);
6299 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6301 color = getPixelColor(device, 160, 360);
6302 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6303 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
6304 color = getPixelColor(device, 480, 360);
6305 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6306 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
6307 if(shader_20) {
6308 color = getPixelColor(device, 480, 120);
6309 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6310 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
6312 if(shader_20_2) {
6313 color = getPixelColor(device, 160, 120);
6314 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6315 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
6317 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6318 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6320 IDirect3DVertexDeclaration9_Release(decl);
6321 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
6322 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
6323 IDirect3DVertexShader9_Release(shader_11_2);
6324 IDirect3DVertexShader9_Release(shader_11);
6325 refcount = IDirect3DDevice9_Release(device);
6326 ok(!refcount, "Device has %u references left.\n", refcount);
6327 done:
6328 IDirect3D9_Release(d3d);
6329 DestroyWindow(window);
6332 static void constant_clamp_ps_test(void)
6334 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
6335 IDirect3DDevice9 *device;
6336 IDirect3D9 *d3d;
6337 ULONG refcount;
6338 D3DCAPS9 caps;
6339 DWORD color;
6340 HWND window;
6341 HRESULT hr;
6343 static const DWORD shader_code_11[] =
6345 0xffff0101, /* ps_1_1 */
6346 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6347 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6348 0x0000ffff /* end */
6350 static const DWORD shader_code_12[] =
6352 0xffff0102, /* ps_1_2 */
6353 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6354 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6355 0x0000ffff /* end */
6357 /* Skip 1.3 shaders because we have only 4 quads (ok, could make them
6358 * smaller if needed). 1.2 and 1.4 shaders behave the same, so it's
6359 * unlikely that 1.3 shaders are different. During development of this
6360 * test, 1.3 shaders were verified too. */
6361 static const DWORD shader_code_14[] =
6363 0xffff0104, /* ps_1_4 */
6364 /* Try to make one constant local. It gets clamped too, although the
6365 * binary contains the bigger numbers. */
6366 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
6367 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6368 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6369 0x0000ffff /* end */
6371 static const DWORD shader_code_20[] =
6373 0xffff0200, /* ps_2_0 */
6374 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6375 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6376 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6377 0x0000ffff /* end */
6379 static const float quad1[] =
6381 -1.0f, -1.0f, 0.1f,
6382 -1.0f, 0.0f, 0.1f,
6383 0.0f, -1.0f, 0.1f,
6384 0.0f, 0.0f, 0.1f,
6386 static const float quad2[] =
6388 0.0f, -1.0f, 0.1f,
6389 0.0f, 0.0f, 0.1f,
6390 1.0f, -1.0f, 0.1f,
6391 1.0f, 0.0f, 0.1f,
6393 static const float quad3[] =
6395 0.0f, 0.0f, 0.1f,
6396 0.0f, 1.0f, 0.1f,
6397 1.0f, 0.0f, 0.1f,
6398 1.0f, 1.0f, 0.1f,
6400 static const float quad4[] =
6402 -1.0f, 0.0f, 0.1f,
6403 -1.0f, 1.0f, 0.1f,
6404 0.0f, 0.0f, 0.1f,
6405 0.0f, 1.0f, 0.1f,
6407 static const float test_data_c1[4] = { 1.25f, -0.50f, -1.50f, 1.0f};
6408 static const float test_data_c2[4] = {-0.50f, 1.25f, 2.00f, 1.0f};
6410 window = create_window();
6411 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6412 ok(!!d3d, "Failed to create a D3D object.\n");
6413 if (!(device = create_device(d3d, window, window, TRUE)))
6415 skip("Failed to create a D3D device, skipping tests.\n");
6416 goto done;
6419 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6420 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6421 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
6423 skip("No ps_1_4 support, skipping tests.\n");
6424 IDirect3DDevice9_Release(device);
6425 goto done;
6428 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
6429 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6431 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
6432 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6433 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
6434 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6435 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
6436 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6437 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
6438 if(FAILED(hr)) shader_20 = NULL;
6440 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
6441 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6442 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
6443 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6444 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6445 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6447 hr = IDirect3DDevice9_BeginScene(device);
6448 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6450 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
6451 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6452 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
6453 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6455 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
6456 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6457 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
6458 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6460 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
6461 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6462 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
6463 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6465 if (shader_20)
6467 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
6468 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6469 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
6470 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6473 hr = IDirect3DDevice9_EndScene(device);
6474 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6476 color = getPixelColor(device, 160, 360);
6477 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
6478 "quad 1 has color %08x, expected 0x00808000\n", color);
6479 color = getPixelColor(device, 480, 360);
6480 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
6481 "quad 2 has color %08x, expected 0x00808000\n", color);
6482 color = getPixelColor(device, 480, 120);
6483 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
6484 "quad 3 has color %08x, expected 0x00808000\n", color);
6485 if(shader_20) {
6486 color = getPixelColor(device, 160, 120);
6487 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6488 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
6490 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6491 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6493 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
6494 IDirect3DPixelShader9_Release(shader_14);
6495 IDirect3DPixelShader9_Release(shader_12);
6496 IDirect3DPixelShader9_Release(shader_11);
6497 refcount = IDirect3DDevice9_Release(device);
6498 ok(!refcount, "Device has %u references left.\n", refcount);
6499 done:
6500 IDirect3D9_Release(d3d);
6501 DestroyWindow(window);
6504 static void dp2add_ps_test(void)
6506 IDirect3DPixelShader9 *shader_dp2add_sat;
6507 IDirect3DPixelShader9 *shader_dp2add;
6508 IDirect3DDevice9 *device;
6509 IDirect3D9 *d3d;
6510 ULONG refcount;
6511 D3DCAPS9 caps;
6512 DWORD color;
6513 HWND window;
6514 HRESULT hr;
6516 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
6517 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
6518 * source tokens can be constants. So, for this exercise, we move contents of c0 to
6519 * r0 first.
6520 * The result here for the r,g,b components should be roughly 0.5:
6521 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
6522 static const DWORD shader_code_dp2add[] = {
6523 0xffff0200, /* ps_2_0 */
6524 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
6526 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6527 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
6529 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
6530 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6531 0x0000ffff /* end */
6534 /* Test the _sat modifier, too. Result here should be:
6535 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
6536 * _SAT: ==> 1.0
6537 * ADD: (1.0 + -0.5) = 0.5
6539 static const DWORD shader_code_dp2add_sat[] = {
6540 0xffff0200, /* ps_2_0 */
6541 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
6543 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6544 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
6545 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
6547 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
6548 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6549 0x0000ffff /* end */
6551 static const float quad[] =
6553 -1.0f, -1.0f, 0.1f,
6554 -1.0f, 1.0f, 0.1f,
6555 1.0f, -1.0f, 0.1f,
6556 1.0f, 1.0f, 0.1f,
6559 window = create_window();
6560 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6561 ok(!!d3d, "Failed to create a D3D object.\n");
6562 if (!(device = create_device(d3d, window, window, TRUE)))
6564 skip("Failed to create a D3D device, skipping tests.\n");
6565 goto done;
6568 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6569 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6570 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
6572 skip("No ps_2_0 support, skipping tests.\n");
6573 IDirect3DDevice9_Release(device);
6574 goto done;
6577 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
6578 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6580 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
6581 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6583 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
6584 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6586 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6587 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6589 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
6590 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
6591 hr = IDirect3DDevice9_BeginScene(device);
6592 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6593 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
6594 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
6595 hr = IDirect3DDevice9_EndScene(device);
6596 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6598 color = getPixelColor(device, 360, 240);
6599 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1), "Got unexpected color 0x%08x.\n", color);
6601 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6602 ok(SUCCEEDED(hr), "Failed to present frame, hr %#x.\n", hr);
6603 IDirect3DPixelShader9_Release(shader_dp2add);
6605 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
6606 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
6607 hr = IDirect3DDevice9_BeginScene(device);
6608 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6609 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
6610 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
6611 hr = IDirect3DDevice9_EndScene(device);
6612 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6614 color = getPixelColor(device, 360, 240);
6615 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1), "Got unexpected color 0x%08x.\n", color);
6617 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6618 ok(SUCCEEDED(hr), "Failed to present frame, hr %#x.\n", hr);
6619 IDirect3DPixelShader9_Release(shader_dp2add_sat);
6621 refcount = IDirect3DDevice9_Release(device);
6622 ok(!refcount, "Device has %u references left.\n", refcount);
6623 done:
6624 IDirect3D9_Release(d3d);
6625 DestroyWindow(window);
6628 static void cnd_test(void)
6630 IDirect3DPixelShader9 *shader_11_coissue_2, *shader_12_coissue_2, *shader_13_coissue_2, *shader_14_coissue_2;
6631 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
6632 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
6633 IDirect3DDevice9 *device;
6634 IDirect3D9 *d3d;
6635 ULONG refcount;
6636 D3DCAPS9 caps;
6637 HWND window;
6638 DWORD color;
6639 HRESULT hr;
6641 /* ps 1.x shaders are rather picky with writemasks and source swizzles.
6642 * The dp3 is used to copy r0.r to all components of r1, then copy r1.a to
6643 * r0.a. Essentially it does a mov r0.a, r0.r, which isn't allowed as-is
6644 * in 1.x pixel shaders. */
6645 static const DWORD shader_code_11[] =
6647 0xffff0101, /* ps_1_1 */
6648 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6649 0x00000040, 0xb00f0000, /* texcoord t0 */
6650 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
6651 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
6652 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6653 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
6654 0x0000ffff /* end */
6656 static const DWORD shader_code_12[] =
6658 0xffff0102, /* ps_1_2 */
6659 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6660 0x00000040, 0xb00f0000, /* texcoord t0 */
6661 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6662 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
6663 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6664 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
6665 0x0000ffff /* end */
6667 static const DWORD shader_code_13[] =
6669 0xffff0103, /* ps_1_3 */
6670 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6671 0x00000040, 0xb00f0000, /* texcoord t0 */
6672 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6673 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
6674 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6675 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
6676 0x0000ffff /* end */
6678 static const DWORD shader_code_14[] =
6680 0xffff0104, /* ps_1_3 */
6681 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6682 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
6683 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
6684 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
6685 0x0000ffff /* end */
6688 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
6689 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
6690 * set by the compiler, it was added manually after compilation. Note that the COISSUE
6691 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
6692 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
6693 * well enough.
6695 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
6696 * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
6697 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
6698 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
6700 static const DWORD shader_code_11_coissue[] =
6702 0xffff0101, /* ps_1_1 */
6703 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6704 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6705 0x00000040, 0xb00f0000, /* texcoord t0 */
6706 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6707 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6708 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6709 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6710 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6711 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6712 0x0000ffff /* end */
6714 static const DWORD shader_code_11_coissue_2[] =
6716 0xffff0101, /* ps_1_1 */
6717 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6718 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6719 0x00000040, 0xb00f0000, /* texcoord t0 */
6720 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6721 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6722 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6723 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6724 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6725 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6726 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6727 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6728 0x0000ffff /* end */
6730 static const DWORD shader_code_12_coissue[] =
6732 0xffff0102, /* ps_1_2 */
6733 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6734 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6735 0x00000040, 0xb00f0000, /* texcoord t0 */
6736 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6737 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6738 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6739 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6740 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6741 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6742 0x0000ffff /* end */
6744 static const DWORD shader_code_12_coissue_2[] =
6746 0xffff0102, /* ps_1_2 */
6747 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6748 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6749 0x00000040, 0xb00f0000, /* texcoord t0 */
6750 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6751 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6752 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6753 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6754 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6755 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6756 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6757 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6758 0x0000ffff /* end */
6760 static const DWORD shader_code_13_coissue[] =
6762 0xffff0103, /* ps_1_3 */
6763 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6764 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6765 0x00000040, 0xb00f0000, /* texcoord t0 */
6766 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6767 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6768 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6769 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6770 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6771 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6772 0x0000ffff /* end */
6774 static const DWORD shader_code_13_coissue_2[] =
6776 0xffff0103, /* ps_1_3 */
6777 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6778 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6779 0x00000040, 0xb00f0000, /* texcoord t0 */
6780 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6781 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6782 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6783 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6784 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6785 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6786 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6787 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6788 0x0000ffff /* end */
6790 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1]
6791 * texcrd result to cnd, it will compare against 0.5. */
6792 static const DWORD shader_code_14_coissue[] =
6794 0xffff0104, /* ps_1_4 */
6795 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6796 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
6797 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
6798 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0, c1, c2 */
6799 0x0000ffff /* end */
6801 static const DWORD shader_code_14_coissue_2[] =
6803 0xffff0104, /* ps_1_4 */
6804 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6805 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
6806 0x00000001, 0x80080000, 0x80000000, /* mov r0.a, r0.x */
6807 0x00000001, 0x80070001, 0xa0ff0000, /* mov r1.xyz, c0.a */
6808 0x40000050, 0x80080001, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r1.a, r0.a, c1, c2 */
6809 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6810 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
6811 0x0000ffff /* end */
6813 static const float quad1[] =
6815 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6816 -1.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6817 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6818 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6820 static const float quad2[] =
6822 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6823 0.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6824 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6825 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6827 static const float quad3[] =
6829 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6830 0.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6831 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6832 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6834 static const float quad4[] =
6836 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6837 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6838 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6839 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6841 static const float test_data_c1[4] = {0.0f, 0.0f, 0.0f, 0.0f};
6842 static const float test_data_c2[4] = {1.0f, 1.0f, 1.0f, 1.0f};
6843 static const float test_data_c1_coi[4] = {0.0f, 1.0f, 0.0f, 0.0f};
6844 static const float test_data_c2_coi[4] = {1.0f, 0.0f, 1.0f, 1.0f};
6846 window = create_window();
6847 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6848 ok(!!d3d, "Failed to create a D3D object.\n");
6849 if (!(device = create_device(d3d, window, window, TRUE)))
6851 skip("Failed to create a D3D device, skipping tests.\n");
6852 goto done;
6855 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6856 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6857 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
6859 skip("No ps_1_4 support, skipping tests.\n");
6860 IDirect3DDevice9_Release(device);
6861 goto done;
6864 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
6865 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6867 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
6868 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6869 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
6870 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6871 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
6872 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6873 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
6874 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6875 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
6876 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6877 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
6878 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6879 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
6880 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6881 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
6882 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6883 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue_2, &shader_11_coissue_2);
6884 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6885 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue_2, &shader_12_coissue_2);
6886 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6887 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue_2, &shader_13_coissue_2);
6888 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6889 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue_2, &shader_14_coissue_2);
6890 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6892 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
6893 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6894 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
6895 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6896 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6897 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6899 hr = IDirect3DDevice9_BeginScene(device);
6900 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6902 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
6903 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6904 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6905 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6907 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
6908 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6909 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
6910 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6912 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
6913 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6914 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
6915 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6917 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
6918 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6919 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
6920 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6922 hr = IDirect3DDevice9_EndScene(device);
6923 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6925 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6926 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6928 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
6929 color = getPixelColor(device, 158, 118);
6930 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
6931 color = getPixelColor(device, 162, 118);
6932 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
6933 color = getPixelColor(device, 158, 122);
6934 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
6935 color = getPixelColor(device, 162, 122);
6936 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
6938 /* 1.1 shader. All 3 components get set, based on the .w comparison */
6939 color = getPixelColor(device, 158, 358);
6940 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
6941 color = getPixelColor(device, 162, 358);
6942 ok(color_match(color, 0x00000000, 1), "pixel 162, 358 has color 0x%08x, expected 0x00000000.\n", color);
6943 color = getPixelColor(device, 158, 362);
6944 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
6945 color = getPixelColor(device, 162, 362);
6946 ok(color_match(color, 0x00000000, 1), "pixel 162, 362 has color 0x%08x, expected 0x00000000.\n", color);
6948 /* 1.2 shader */
6949 color = getPixelColor(device, 478, 358);
6950 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
6951 color = getPixelColor(device, 482, 358);
6952 ok(color_match(color, 0x00000000, 1), "pixel 482, 358 has color 0x%08x, expected 0x00000000.\n", color);
6953 color = getPixelColor(device, 478, 362);
6954 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
6955 color = getPixelColor(device, 482, 362);
6956 ok(color_match(color, 0x00000000, 1), "pixel 482, 362 has color 0x%08x, expected 0x00000000.\n", color);
6958 /* 1.3 shader */
6959 color = getPixelColor(device, 478, 118);
6960 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
6961 color = getPixelColor(device, 482, 118);
6962 ok(color_match(color, 0x00000000, 1), "pixel 482, 118 has color 0x%08x, expected 0x00000000.\n", color);
6963 color = getPixelColor(device, 478, 122);
6964 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
6965 color = getPixelColor(device, 482, 122);
6966 ok(color_match(color, 0x00000000, 1), "pixel 482, 122 has color 0x%08x, expected 0x00000000.\n", color);
6968 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6969 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6971 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
6972 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6973 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
6974 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6975 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
6976 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6978 hr = IDirect3DDevice9_BeginScene(device);
6979 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6981 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
6982 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6983 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6984 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6986 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
6987 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6988 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
6989 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6991 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
6992 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6993 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
6994 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6996 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
6997 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6998 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
6999 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7001 hr = IDirect3DDevice9_EndScene(device);
7002 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7004 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7005 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7007 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
7008 * that we swapped the values in c1 and c2 to make the other tests return some color
7010 color = getPixelColor(device, 158, 118);
7011 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
7012 color = getPixelColor(device, 162, 118);
7013 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
7014 color = getPixelColor(device, 158, 122);
7015 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
7016 color = getPixelColor(device, 162, 122);
7017 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
7019 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
7020 * (The Win7 nvidia driver always selects c2)
7022 color = getPixelColor(device, 158, 358);
7023 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7024 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
7025 color = getPixelColor(device, 162, 358);
7026 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7027 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
7028 color = getPixelColor(device, 158, 362);
7029 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7030 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
7031 color = getPixelColor(device, 162, 362);
7032 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7033 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
7035 /* 1.2 shader */
7036 color = getPixelColor(device, 478, 358);
7037 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7038 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
7039 color = getPixelColor(device, 482, 358);
7040 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7041 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
7042 color = getPixelColor(device, 478, 362);
7043 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7044 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
7045 color = getPixelColor(device, 482, 362);
7046 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7047 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
7049 /* 1.3 shader */
7050 color = getPixelColor(device, 478, 118);
7051 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7052 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
7053 color = getPixelColor(device, 482, 118);
7054 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7055 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
7056 color = getPixelColor(device, 478, 122);
7057 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7058 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
7059 color = getPixelColor(device, 482, 122);
7060 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7061 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
7063 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7064 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7066 /* Retest with the coissue flag on the alpha instruction instead. This
7067 * works "as expected". The Windows 8 testbot (WARP) seems to handle this
7068 * the same as coissue on .rgb. */
7069 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
7070 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7072 hr = IDirect3DDevice9_BeginScene(device);
7073 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7075 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue_2);
7076 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
7077 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
7078 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7080 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue_2);
7081 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
7082 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
7083 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7085 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue_2);
7086 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
7087 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
7088 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7090 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue_2);
7091 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
7092 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
7093 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7095 hr = IDirect3DDevice9_EndScene(device);
7096 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7098 /* 1.4 shader */
7099 color = getPixelColor(device, 158, 118);
7100 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
7101 color = getPixelColor(device, 162, 118);
7102 ok(color == 0x00000000, "pixel 162, 118 has color %08x, expected 0x00000000\n", color);
7103 color = getPixelColor(device, 158, 122);
7104 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
7105 color = getPixelColor(device, 162, 122);
7106 ok(color == 0x00000000, "pixel 162, 122 has color %08x, expected 0x00000000\n", color);
7108 /* 1.1 shader */
7109 color = getPixelColor(device, 238, 358);
7110 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
7111 "pixel 238, 358 has color %08x, expected 0x00ffffff\n", color);
7112 color = getPixelColor(device, 242, 358);
7113 ok(color_match(color, 0x00000000, 1),
7114 "pixel 242, 358 has color %08x, expected 0x00000000\n", color);
7115 color = getPixelColor(device, 238, 362);
7116 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
7117 "pixel 238, 362 has color %08x, expected 0x00ffffff\n", color);
7118 color = getPixelColor(device, 242, 362);
7119 ok(color_match(color, 0x00000000, 1),
7120 "pixel 242, 362 has color %08x, expected 0x00000000\n", color);
7122 /* 1.2 shader */
7123 color = getPixelColor(device, 558, 358);
7124 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
7125 "pixel 558, 358 has color %08x, expected 0x00ffffff\n", color);
7126 color = getPixelColor(device, 562, 358);
7127 ok(color_match(color, 0x00000000, 1),
7128 "pixel 562, 358 has color %08x, expected 0x00000000\n", color);
7129 color = getPixelColor(device, 558, 362);
7130 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
7131 "pixel 558, 362 has color %08x, expected 0x00ffffff\n", color);
7132 color = getPixelColor(device, 562, 362);
7133 ok(color_match(color, 0x00000000, 1),
7134 "pixel 562, 362 has color %08x, expected 0x00000000\n", color);
7136 /* 1.3 shader */
7137 color = getPixelColor(device, 558, 118);
7138 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
7139 "pixel 558, 118 has color %08x, expected 0x00ffffff\n", color);
7140 color = getPixelColor(device, 562, 118);
7141 ok(color_match(color, 0x00000000, 1),
7142 "pixel 562, 118 has color %08x, expected 0x00000000\n", color);
7143 color = getPixelColor(device, 558, 122);
7144 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
7145 "pixel 558, 122 has color %08x, expected 0x00ffffff\n", color);
7146 color = getPixelColor(device, 562, 122);
7147 ok(color_match(color, 0x00000000, 1),
7148 "pixel 562, 122 has color %08x, expected 0x00000000\n", color);
7150 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7151 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7153 IDirect3DPixelShader9_Release(shader_14_coissue_2);
7154 IDirect3DPixelShader9_Release(shader_13_coissue_2);
7155 IDirect3DPixelShader9_Release(shader_12_coissue_2);
7156 IDirect3DPixelShader9_Release(shader_11_coissue_2);
7157 IDirect3DPixelShader9_Release(shader_14_coissue);
7158 IDirect3DPixelShader9_Release(shader_13_coissue);
7159 IDirect3DPixelShader9_Release(shader_12_coissue);
7160 IDirect3DPixelShader9_Release(shader_11_coissue);
7161 IDirect3DPixelShader9_Release(shader_14);
7162 IDirect3DPixelShader9_Release(shader_13);
7163 IDirect3DPixelShader9_Release(shader_12);
7164 IDirect3DPixelShader9_Release(shader_11);
7165 refcount = IDirect3DDevice9_Release(device);
7166 ok(!refcount, "Device has %u references left.\n", refcount);
7167 done:
7168 IDirect3D9_Release(d3d);
7169 DestroyWindow(window);
7172 static void nested_loop_test(void)
7174 IDirect3DVertexShader9 *vshader;
7175 IDirect3DPixelShader9 *shader;
7176 IDirect3DDevice9 *device;
7177 IDirect3D9 *d3d;
7178 ULONG refcount;
7179 D3DCAPS9 caps;
7180 DWORD color;
7181 HWND window;
7182 HRESULT hr;
7184 static const DWORD shader_code[] =
7186 0xffff0300, /* ps_3_0 */
7187 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
7188 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
7189 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
7190 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7191 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
7192 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
7193 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
7194 0x0000001d, /* endloop */
7195 0x0000001d, /* endloop */
7196 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7197 0x0000ffff /* end */
7199 static const DWORD vshader_code[] =
7201 0xfffe0300, /* vs_3_0 */
7202 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7203 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7204 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7205 0x0000ffff /* end */
7207 static const float quad[] =
7209 -1.0f, -1.0f, 0.1f,
7210 -1.0f, 1.0f, 0.1f,
7211 1.0f, -1.0f, 0.1f,
7212 1.0f, 1.0f, 0.1f,
7215 window = create_window();
7216 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7217 ok(!!d3d, "Failed to create a D3D object.\n");
7218 if (!(device = create_device(d3d, window, window, TRUE)))
7220 skip("Failed to create a D3D device, skipping tests.\n");
7221 goto done;
7224 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7225 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7226 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
7228 skip("No shader model 3 support, skipping tests.\n");
7229 IDirect3DDevice9_Release(device);
7230 goto done;
7233 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7234 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
7235 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7236 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
7237 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
7238 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
7239 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
7240 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
7241 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7242 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
7243 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 1.0f, 0);
7244 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7246 hr = IDirect3DDevice9_BeginScene(device);
7247 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7248 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
7249 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7250 hr = IDirect3DDevice9_EndScene(device);
7251 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7253 color = getPixelColor(device, 360, 240);
7254 ok(color_match(color, 0x00800000, 1),
7255 "Nested loop test returned color 0x%08x, expected 0x00800000.\n", color);
7257 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7258 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7260 IDirect3DPixelShader9_Release(shader);
7261 IDirect3DVertexShader9_Release(vshader);
7262 refcount = IDirect3DDevice9_Release(device);
7263 ok(!refcount, "Device has %u references left.\n", refcount);
7264 done:
7265 IDirect3D9_Release(d3d);
7266 DestroyWindow(window);
7269 static void pretransformed_varying_test(void)
7271 /* dcl_position: fails to compile */
7272 static const DWORD blendweight_code[] =
7274 0xffff0300, /* ps_3_0 */
7275 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
7276 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7277 0x0000ffff /* end */
7279 static const DWORD blendindices_code[] =
7281 0xffff0300, /* ps_3_0 */
7282 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
7283 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7284 0x0000ffff /* end */
7286 static const DWORD normal_code[] =
7288 0xffff0300, /* ps_3_0 */
7289 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
7290 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7291 0x0000ffff /* end */
7293 /* psize: fails? */
7294 static const DWORD texcoord0_code[] =
7296 0xffff0300, /* ps_3_0 */
7297 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
7298 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7299 0x0000ffff /* end */
7301 static const DWORD tangent_code[] =
7303 0xffff0300, /* ps_3_0 */
7304 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
7305 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7306 0x0000ffff /* end */
7308 static const DWORD binormal_code[] =
7310 0xffff0300, /* ps_3_0 */
7311 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
7312 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7313 0x0000ffff /* end */
7315 /* tessfactor: fails */
7316 /* positiont: fails */
7317 static const DWORD color_code[] =
7319 0xffff0300, /* ps_3_0 */
7320 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
7321 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7322 0x0000ffff /* end */
7324 static const DWORD fog_code[] =
7326 0xffff0300, /* ps_3_0 */
7327 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
7328 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7329 0x0000ffff /* end */
7331 static const DWORD depth_code[] =
7333 0xffff0300, /* ps_3_0 */
7334 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
7335 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7336 0x0000ffff /* end */
7338 static const DWORD specular_code[] =
7340 0xffff0300, /* ps_3_0 */
7341 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
7342 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7343 0x0000ffff /* end */
7345 /* sample: fails */
7346 static const DWORD texcoord1_code[] =
7348 0xffff0300, /* ps_3_0 */
7349 0x0200001f, 0x80010005, 0x900f0000, /* dcl_texcoord1, v0 */
7350 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7351 0x0000ffff /* end */
7353 static const DWORD texcoord1_alpha_code[] =
7355 0xffff0300, /* ps_3_0 */
7356 0x0200001f, 0x80010005, 0x900f0000, /* dcl_texcoord1, v0 */
7357 0x02000001, 0x800f0800, 0x90ff0000, /* mov oC0, v0.w */
7358 0x0000ffff /* end */
7361 static const struct
7363 const char *name;
7364 const DWORD *shader_code;
7365 DWORD color;
7366 BOOL todo;
7367 BOOL broken;
7368 DWORD broken_color;
7370 tests[] =
7372 {"blendweight", blendweight_code, 0x00191919, TRUE },
7373 {"blendindices", blendindices_code, 0x00333333, TRUE },
7374 {"normal", normal_code, 0x004c4c4c, TRUE },
7375 {"texcoord0", texcoord0_code, 0x00808c8c, FALSE},
7376 {"tangent", tangent_code, 0x00999999, TRUE },
7377 {"binormal", binormal_code, 0x00b2b2b2, TRUE },
7378 {"color", color_code, 0x00e6e6e6, FALSE},
7379 {"fog", fog_code, 0x00666666, TRUE },
7380 {"depth", depth_code, 0x00cccccc, TRUE },
7381 {"specular", specular_code, 0x004488ff, FALSE},
7382 {"texcoord1", texcoord1_code, 0x00000000, FALSE},
7383 /* texcoord .w is 1.0 on r500 and WARP. See also test_uninitialized_varyings(). */
7384 {"texcoord1 alpha", texcoord1_alpha_code, 0x00000000, FALSE, TRUE, 0x00ffffff},
7386 /* Declare a monster vertex type :-) */
7387 static const D3DVERTEXELEMENT9 decl_elements[] = {
7388 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
7389 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
7390 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
7391 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
7392 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
7393 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7394 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
7395 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
7396 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
7397 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7398 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
7399 D3DDECL_END()
7402 static const struct
7404 float pos_x, pos_y, pos_z, rhw;
7405 float weight_1, weight_2, weight_3, weight_4;
7406 float index_1, index_2, index_3, index_4;
7407 float normal_1, normal_2, normal_3, normal_4;
7408 float fog_1, fog_2, fog_3, fog_4;
7409 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
7410 float tangent_1, tangent_2, tangent_3, tangent_4;
7411 float binormal_1, binormal_2, binormal_3, binormal_4;
7412 float depth_1, depth_2, depth_3, depth_4;
7413 D3DCOLOR diffuse;
7414 D3DCOLOR specular;
7416 data[] =
7419 0.0f, 0.0f, 0.1f, 1.0f,
7420 0.1f, 0.1f, 0.1f, 0.1f,
7421 0.2f, 0.2f, 0.2f, 0.2f,
7422 0.3f, 0.3f, 0.3f, 0.3f,
7423 0.4f, 0.4f, 0.4f, 0.4f,
7424 0.5f, 0.55f, 0.55f, 0.55f,
7425 0.6f, 0.6f, 0.6f, 0.7f,
7426 0.7f, 0.7f, 0.7f, 0.6f,
7427 0.8f, 0.8f, 0.8f, 0.8f,
7428 0xe6e6e6e6, /* 0.9 * 256 */
7429 0x224488ff, /* Nothing special */
7432 640.0f, 0.0f, 0.1f, 1.0f,
7433 0.1f, 0.1f, 0.1f, 0.1f,
7434 0.2f, 0.2f, 0.2f, 0.2f,
7435 0.3f, 0.3f, 0.3f, 0.3f,
7436 0.4f, 0.4f, 0.4f, 0.4f,
7437 0.5f, 0.55f, 0.55f, 0.55f,
7438 0.6f, 0.6f, 0.6f, 0.7f,
7439 0.7f, 0.7f, 0.7f, 0.6f,
7440 0.8f, 0.8f, 0.8f, 0.8f,
7441 0xe6e6e6e6, /* 0.9 * 256 */
7442 0x224488ff, /* Nothing special */
7445 0.0f, 480.0f, 0.1f, 1.0f,
7446 0.1f, 0.1f, 0.1f, 0.1f,
7447 0.2f, 0.2f, 0.2f, 0.2f,
7448 0.3f, 0.3f, 0.3f, 0.3f,
7449 0.4f, 0.4f, 0.4f, 0.4f,
7450 0.5f, 0.55f, 0.55f, 0.55f,
7451 0.6f, 0.6f, 0.6f, 0.7f,
7452 0.7f, 0.7f, 0.7f, 0.6f,
7453 0.8f, 0.8f, 0.8f, 0.8f,
7454 0xe6e6e6e6, /* 0.9 * 256 */
7455 0x224488ff, /* Nothing special */
7458 640.0f, 480.0f, 0.1f, 1.0f,
7459 0.1f, 0.1f, 0.1f, 0.1f,
7460 0.2f, 0.2f, 0.2f, 0.2f,
7461 0.3f, 0.3f, 0.3f, 0.3f,
7462 0.4f, 0.4f, 0.4f, 0.4f,
7463 0.5f, 0.55f, 0.55f, 0.55f,
7464 0.6f, 0.6f, 0.6f, 0.7f,
7465 0.7f, 0.7f, 0.7f, 0.6f,
7466 0.8f, 0.8f, 0.8f, 0.8f,
7467 0xe6e6e6e6, /* 0.9 * 256 */
7468 0x224488ff, /* Nothing special */
7471 IDirect3DVertexDeclaration9 *decl;
7472 IDirect3DDevice9 *device;
7473 IDirect3D9 *d3d;
7474 unsigned int i;
7475 ULONG refcount;
7476 D3DCAPS9 caps;
7477 DWORD color;
7478 HWND window;
7479 HRESULT hr;
7481 window = create_window();
7482 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7483 ok(!!d3d, "Failed to create a D3D object.\n");
7484 if (!(device = create_device(d3d, window, window, TRUE)))
7486 skip("Failed to create a D3D device, skipping tests.\n");
7487 goto done;
7490 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7491 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7492 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
7494 skip("No shader model 3 support, skipping tests.\n");
7495 IDirect3DDevice9_Release(device);
7496 goto done;
7499 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
7500 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7501 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
7502 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
7504 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
7506 IDirect3DPixelShader9 *shader;
7508 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
7509 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7511 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &shader);
7512 ok(SUCCEEDED(hr), "Failed to create pixel shader for test %s, hr %#x.\n", tests[i].name, hr);
7514 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7515 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7517 hr = IDirect3DDevice9_BeginScene(device);
7518 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7519 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(*data));
7520 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7521 hr = IDirect3DDevice9_EndScene(device);
7522 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7524 /* This isn't a weekend's job to fix, ignore the problem for now.
7525 * Needs a replacement pipeline. */
7526 color = getPixelColor(device, 360, 240);
7527 if (tests[i].todo)
7528 todo_wine ok(color_match(color, tests[i].color, 1)
7529 || broken(color_match(color, 0x00000000, 1)
7530 && tests[i].shader_code == blendindices_code),
7531 "Test %s returned color 0x%08x, expected 0x%08x (todo).\n",
7532 tests[i].name, color, tests[i].color);
7533 else
7534 ok(color_match(color, tests[i].color, 1)
7535 || broken(color_match(color, tests[i].broken_color, 1) && tests[i].broken),
7536 "Test %s returned color 0x%08x, expected 0x%08x.\n",
7537 tests[i].name, color, tests[i].color);
7539 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7540 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7542 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7543 ok(SUCCEEDED(hr), "Failed to set pixel shader for test %s, hr %#x.\n", tests[i].name, hr);
7544 IDirect3DPixelShader9_Release(shader);
7547 IDirect3DVertexDeclaration9_Release(decl);
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_compare_instructions(void)
7557 IDirect3DVertexShader9 *shader_slt_scalar;
7558 IDirect3DVertexShader9 *shader_sge_scalar;
7559 IDirect3DVertexShader9 *shader_slt_vec;
7560 IDirect3DVertexShader9 *shader_sge_vec;
7561 IDirect3DDevice9 *device;
7562 IDirect3D9 *d3d;
7563 D3DCOLOR color;
7564 ULONG refcount;
7565 D3DCAPS9 caps;
7566 HWND window;
7567 HRESULT hr;
7569 static const DWORD shader_sge_vec_code[] =
7571 0xfffe0101, /* vs_1_1 */
7572 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7573 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7574 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7575 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
7576 0x0000ffff /* end */
7578 static const DWORD shader_slt_vec_code[] =
7580 0xfffe0101, /* vs_1_1 */
7581 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7582 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7583 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7584 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
7585 0x0000ffff /* end */
7587 static const DWORD shader_sge_scalar_code[] =
7589 0xfffe0101, /* vs_1_1 */
7590 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7591 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7592 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7593 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
7594 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
7595 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
7596 0x0000ffff /* end */
7598 static const DWORD shader_slt_scalar_code[] =
7600 0xfffe0101, /* vs_1_1 */
7601 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7602 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7603 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7604 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
7605 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
7606 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
7607 0x0000ffff /* end */
7609 static const float quad1[] =
7611 -1.0f, -1.0f, 0.1f,
7612 -1.0f, 0.0f, 0.1f,
7613 0.0f, -1.0f, 0.1f,
7614 0.0f, 0.0f, 0.1f,
7616 static const float quad2[] =
7618 0.0f, -1.0f, 0.1f,
7619 0.0f, 0.0f, 0.1f,
7620 1.0f, -1.0f, 0.1f,
7621 1.0f, 0.0f, 0.1f,
7623 static const float quad3[] =
7625 -1.0f, 0.0f, 0.1f,
7626 -1.0f, 1.0f, 0.1f,
7627 0.0f, 0.0f, 0.1f,
7628 0.0f, 1.0f, 0.1f,
7630 static const float quad4[] =
7632 0.0f, 0.0f, 0.1f,
7633 0.0f, 1.0f, 0.1f,
7634 1.0f, 0.0f, 0.1f,
7635 1.0f, 1.0f, 0.1f,
7637 static const float const0[4] = {0.8f, 0.2f, 0.2f, 0.2f};
7638 static const float const1[4] = {0.2f, 0.8f, 0.2f, 0.2f};
7640 window = create_window();
7641 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7642 ok(!!d3d, "Failed to create a D3D object.\n");
7643 if (!(device = create_device(d3d, window, window, TRUE)))
7645 skip("Failed to create a D3D device, skipping tests.\n");
7646 goto done;
7649 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7650 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7651 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
7653 skip("No vs_1_1 support, skipping tests.\n");
7654 IDirect3DDevice9_Release(device);
7655 goto done;
7658 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
7659 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
7661 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
7662 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7663 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
7664 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7665 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
7666 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7667 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
7668 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7669 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
7670 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
7671 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
7672 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
7673 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7674 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
7676 hr = IDirect3DDevice9_BeginScene(device);
7677 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7679 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
7680 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7681 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
7682 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7684 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
7685 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7686 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
7687 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7689 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
7690 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7691 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
7692 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7694 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
7695 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
7697 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
7698 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7699 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
7700 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7702 hr = IDirect3DDevice9_EndScene(device);
7703 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7705 color = getPixelColor(device, 160, 360);
7706 ok(color == 0x00ff00ff, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00ff00ff\n", color);
7707 color = getPixelColor(device, 480, 360);
7708 ok(color == 0x0000ff00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000ff00\n", color);
7709 color = getPixelColor(device, 160, 120);
7710 ok(color == 0x00ffffff, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00ffffff\n", color);
7711 color = getPixelColor(device, 480, 160);
7712 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
7714 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7715 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7717 IDirect3DVertexShader9_Release(shader_sge_vec);
7718 IDirect3DVertexShader9_Release(shader_slt_vec);
7719 IDirect3DVertexShader9_Release(shader_sge_scalar);
7720 IDirect3DVertexShader9_Release(shader_slt_scalar);
7721 refcount = IDirect3DDevice9_Release(device);
7722 ok(!refcount, "Device has %u references left.\n", refcount);
7723 done:
7724 IDirect3D9_Release(d3d);
7725 DestroyWindow(window);
7728 static void test_vshader_input(void)
7730 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
7731 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
7732 IDirect3DVertexDeclaration9 *decl_nocolor;
7733 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
7734 D3DADAPTER_IDENTIFIER9 identifier;
7735 IDirect3DPixelShader9 *ps;
7736 IDirect3DDevice9 *device;
7737 IDirect3D9 *d3d;
7738 ULONG refcount;
7739 unsigned int i;
7740 D3DCAPS9 caps;
7741 DWORD color;
7742 HWND window;
7743 HRESULT hr;
7744 BOOL warp;
7746 static const DWORD swapped_shader_code_3[] =
7748 0xfffe0300, /* vs_3_0 */
7749 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7750 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7751 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7752 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7753 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7754 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7755 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7756 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7757 0x0000ffff /* end */
7759 static const DWORD swapped_shader_code_1[] =
7761 0xfffe0101, /* vs_1_1 */
7762 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7763 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7764 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7765 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
7766 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7767 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7768 0x0000ffff /* end */
7770 static const DWORD swapped_shader_code_2[] =
7772 0xfffe0200, /* vs_2_0 */
7773 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7774 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7775 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7776 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
7777 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7778 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7779 0x0000ffff /* end */
7781 static const DWORD texcoord_color_shader_code_3[] =
7783 0xfffe0300, /* vs_3_0 */
7784 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7785 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7786 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7787 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7788 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7789 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
7790 0x0000ffff /* end */
7792 static const DWORD texcoord_color_shader_code_2[] =
7794 0xfffe0200, /* vs_2_0 */
7795 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7796 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7797 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7798 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
7799 0x0000ffff /* end */
7801 static const DWORD texcoord_color_shader_code_1[] =
7803 0xfffe0101, /* vs_1_1 */
7804 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7805 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7806 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7807 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
7808 0x0000ffff /* end */
7810 static const DWORD color_color_shader_code_3[] =
7812 0xfffe0300, /* vs_3_0 */
7813 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7814 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7815 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7816 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7817 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7818 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
7819 0x0000ffff /* end */
7821 static const DWORD color_color_shader_code_2[] =
7823 0xfffe0200, /* vs_2_0 */
7824 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7825 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7826 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7827 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
7828 0x0000ffff /* end */
7830 static const DWORD color_color_shader_code_1[] =
7832 0xfffe0101, /* vs_1_1 */
7833 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7834 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7835 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7836 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
7837 0x0000ffff /* end */
7839 static const DWORD ps3_code[] =
7841 0xffff0300, /* ps_3_0 */
7842 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
7843 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7844 0x0000ffff /* end */
7846 static const float quad1[] =
7848 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7849 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7850 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7851 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7853 static const float quad2[] =
7855 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7856 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7857 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7858 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7860 static const float quad3[] =
7862 -1.0f, 0.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f,
7863 -1.0f, 1.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
7864 0.0f, 0.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
7865 0.0f, 1.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
7867 static const float quad4[] =
7869 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7870 0.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7871 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7872 1.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7874 static const float quad1_modified[] =
7876 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
7877 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f,
7878 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
7879 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, -1.0f, -1.0f, 0.0f,
7881 static const float quad2_modified[] =
7883 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7884 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7885 1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7886 1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7888 static const struct
7890 struct vec3 position;
7891 DWORD diffuse;
7893 quad1_color[] =
7895 {{-1.0f, -1.0f, 0.1f}, 0x00ff8040},
7896 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
7897 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7898 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7900 quad2_color[] =
7902 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7903 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7904 {{ 1.0f, -1.0f, 0.1f}, 0x00ff8040},
7905 {{ 1.0f, 0.0f, 0.1f}, 0x00ff8040},
7907 quad3_color[] =
7909 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
7910 {{-1.0f, 1.0f, 0.1f}, 0x00ff8040},
7911 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7912 {{ 0.0f, 1.0f, 0.1f}, 0x00ff8040},
7914 static const float quad4_color[] =
7916 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7917 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7918 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7919 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7921 static const struct vec3 quad_nocolor[] =
7923 {-1.0f, -1.0f, 0.1f},
7924 {-1.0f, 1.0f, 0.1f},
7925 { 1.0f, -1.0f, 0.1f},
7926 { 1.0f, 1.0f, 0.1f},
7928 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] =
7930 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7931 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7932 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7933 D3DDECL_END()
7935 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] =
7937 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7938 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7939 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7940 D3DDECL_END()
7942 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] =
7944 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7945 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7946 D3DDECL_END()
7948 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] =
7950 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7951 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7952 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
7953 D3DDECL_END()
7955 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] =
7957 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7958 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7959 D3DDECL_END()
7961 static const D3DVERTEXELEMENT9 decl_elements_color_color[] =
7963 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7964 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7965 D3DDECL_END()
7967 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] =
7969 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7970 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7971 D3DDECL_END()
7973 static const D3DVERTEXELEMENT9 decl_elements_color_float[] =
7975 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7976 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7977 D3DDECL_END()
7979 static const D3DVERTEXELEMENT9 decl_elements_nocolor[] =
7981 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7982 D3DDECL_END()
7984 static const float normalize[4] = {1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f};
7985 static const float no_normalize[4] = {1.0f, 1.0f, 1.0f, 1.0f};
7987 window = create_window();
7988 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7989 ok(!!d3d, "Failed to create a D3D object.\n");
7990 if (!(device = create_device(d3d, window, window, TRUE)))
7992 skip("Failed to create a D3D device, skipping tests.\n");
7993 goto done;
7996 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7997 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7998 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
8000 skip("No vs_3_0 support, skipping tests.\n");
8001 IDirect3DDevice9_Release(device);
8002 goto done;
8004 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
8006 skip("No ps_3_0 support, skipping tests.\n");
8007 IDirect3DDevice9_Release(device);
8008 goto done;
8011 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
8012 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
8013 warp = adapter_is_warp(&identifier);
8015 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
8016 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
8017 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
8018 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
8019 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
8020 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
8021 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
8022 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
8024 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
8025 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
8026 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
8027 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
8028 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
8029 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
8030 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
8031 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
8032 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_nocolor, &decl_nocolor);
8033 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
8035 hr = IDirect3DDevice9_CreatePixelShader(device, ps3_code, &ps);
8036 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
8038 for (i = 1; i <= 3; ++i)
8040 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
8041 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
8042 if(i == 3) {
8043 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
8044 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8045 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8046 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
8047 } else if(i == 2){
8048 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
8049 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8050 } else if(i == 1) {
8051 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
8052 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8055 hr = IDirect3DDevice9_BeginScene(device);
8056 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8058 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
8059 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8061 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
8062 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8063 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
8064 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8066 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
8067 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8068 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
8069 if (i == 3 || i == 2)
8070 ok(SUCCEEDED(hr), "Failed to draw, i %u, hr %#x.\n", i, hr);
8071 else if (i == 1)
8072 /* Succeeds or fails, depending on SW or HW vertex processing. */
8073 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
8075 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
8076 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8077 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
8078 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8080 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
8081 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8082 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
8083 if (i == 3 || i == 2)
8084 ok(SUCCEEDED(hr), "Failed to draw, i %u, hr %#x.\n", i, hr);
8085 else if (i == 1)
8086 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
8088 hr = IDirect3DDevice9_EndScene(device);
8089 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8091 if(i == 3 || i == 2) {
8092 color = getPixelColor(device, 160, 360);
8093 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
8094 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00ffff80\n", color);
8096 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
8097 color = getPixelColor(device, 480, 360);
8098 /* On the Windows 8 testbot (WARP) the draw succeeds, but uses
8099 * mostly random data as input. */
8100 ok(color == 0x00ffff00 || color == 0x00ff0000 || broken(warp),
8101 "Got unexpected color 0x%08x for quad 2 (1crd).\n", color);
8102 color = getPixelColor(device, 160, 120);
8103 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
8104 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
8105 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00ff0080\n", color);
8107 color = getPixelColor(device, 480, 160);
8108 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
8109 } else if(i == 1) {
8110 color = getPixelColor(device, 160, 360);
8111 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
8112 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00ffff80\n", color);
8113 color = getPixelColor(device, 480, 360);
8114 /* Accept the clear color as well in this case, since SW VP
8115 * returns an error. On the Windows 8 testbot (WARP) the draw
8116 * succeeds, but uses mostly random data as input. */
8117 ok(color == 0x00ffff00 || color == 0x00ff0000 || broken(warp),
8118 "Got unexpected color 0x%08x for quad 2 (1crd).\n", color);
8119 color = getPixelColor(device, 160, 120);
8120 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
8121 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00ff0080\n", color);
8122 color = getPixelColor(device, 480, 160);
8123 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
8126 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8127 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8129 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
8130 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8132 /* Now find out if the whole streams are re-read, or just the last
8133 * active value for the vertices is used. */
8134 hr = IDirect3DDevice9_BeginScene(device);
8135 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8137 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
8138 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8140 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
8141 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8142 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
8143 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8145 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
8146 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8147 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
8148 if (i == 3 || i == 2)
8149 ok(SUCCEEDED(hr), "Failed to draw, i %u, hr %#x.\n", i, hr);
8150 else if (i == 1)
8151 /* Succeeds or fails, depending on SW or HW vertex processing. */
8152 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
8154 hr = IDirect3DDevice9_EndScene(device);
8155 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8157 color = getPixelColor(device, 480, 350);
8158 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
8159 * as well.
8161 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
8162 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
8163 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
8164 * refrast's result.
8166 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
8168 ok(color == 0x000000ff || color == 0x00808080 || color == 0x00000000
8169 || broken(color_match(color, D3DCOLOR_ARGB(0x00, 0x0b, 0x75, 0x80), 1)),
8170 "Got unexpected color 0x%08x for quad 2 (different colors).\n", color);
8172 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8173 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8175 IDirect3DDevice9_SetVertexShader(device, NULL);
8176 IDirect3DDevice9_SetPixelShader(device, NULL);
8177 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8179 IDirect3DVertexShader9_Release(swapped_shader);
8182 for (i = 1; i <= 3; ++i)
8184 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
8185 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
8186 if(i == 3) {
8187 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
8188 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8189 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
8190 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8191 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8192 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
8193 } else if(i == 2){
8194 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
8195 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8196 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
8197 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8198 } else if(i == 1) {
8199 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
8200 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8201 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
8202 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8205 hr = IDirect3DDevice9_BeginScene(device);
8206 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8208 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
8209 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8210 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
8211 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8212 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
8213 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8215 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
8216 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8218 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
8219 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
8220 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
8221 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8222 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
8223 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8225 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
8226 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
8227 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
8228 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8229 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
8230 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8232 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
8233 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8234 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
8235 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8237 hr = IDirect3DDevice9_EndScene(device);
8238 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8240 color = getPixelColor(device, 160, 360);
8241 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
8242 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
8243 color = getPixelColor(device, 480, 360);
8244 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
8245 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
8246 color = getPixelColor(device, 160, 120);
8247 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
8248 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
8249 color = getPixelColor(device, 480, 160);
8250 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
8251 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00ffff00\n", color);
8253 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8254 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8256 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_nocolor);
8257 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8259 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
8260 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8262 hr = IDirect3DDevice9_BeginScene(device);
8263 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8264 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_nocolor, sizeof(quad_nocolor[0]));
8265 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8266 hr = IDirect3DDevice9_EndScene(device);
8267 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8269 /* WARP and r500 return a color from a previous draw. In case of WARP it is random, although most of the
8270 * time it is the color of the last draw, which happens to be the one with quad4_color above. AMD's r500
8271 * uses the last D3DCOLOR attribute, which is the one from quad3_color.
8273 * Newer AMD cards and Nvidia return zero. */
8274 color = getPixelColor(device, 160, 360);
8275 ok(color_match(color, 0x00000000, 1) || broken(color_match(color, 0x00ff8040, 1)) || broken(warp),
8276 "Got unexpected color 0x%08x for no color attribute test.\n", color);
8278 IDirect3DDevice9_SetVertexShader(device, NULL);
8279 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8280 IDirect3DDevice9_SetPixelShader(device, NULL);
8282 IDirect3DVertexShader9_Release(texcoord_color_shader);
8283 IDirect3DVertexShader9_Release(color_color_shader);
8286 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
8287 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
8288 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
8289 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
8291 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
8292 IDirect3DVertexDeclaration9_Release(decl_color_color);
8293 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
8294 IDirect3DVertexDeclaration9_Release(decl_color_float);
8295 IDirect3DVertexDeclaration9_Release(decl_nocolor);
8297 IDirect3DPixelShader9_Release(ps);
8298 refcount = IDirect3DDevice9_Release(device);
8299 ok(!refcount, "Device has %u references left.\n", refcount);
8300 done:
8301 IDirect3D9_Release(d3d);
8302 DestroyWindow(window);
8305 static void srgbtexture_test(void)
8307 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
8308 * texture stage state to render a quad using that texture. The resulting
8309 * color components should be 0x36 (~ 0.21), per this formula:
8310 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
8311 * This is true where srgb_color > 0.04045. */
8312 struct IDirect3DTexture9 *texture;
8313 struct IDirect3DSurface9 *surface;
8314 IDirect3DDevice9 *device;
8315 IDirect3D9 *d3d;
8316 D3DCOLOR color;
8317 ULONG refcount;
8318 HWND window;
8319 HRESULT hr;
8321 static const float quad[] =
8323 -1.0f, -1.0f, 0.0f, 0.0f, 1.0f,
8324 -1.0f, 1.0f, 0.0f, 0.0f, 0.0f,
8325 1.0f, -1.0f, 0.0f, 1.0f, 1.0f,
8326 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
8329 window = create_window();
8330 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8331 ok(!!d3d, "Failed to create a D3D object.\n");
8332 if (!(device = create_device(d3d, window, window, TRUE)))
8334 skip("Failed to create a D3D device, skipping tests.\n");
8335 goto done;
8338 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
8339 D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK)
8341 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported.\n");
8342 IDirect3DDevice9_Release(device);
8343 goto done;
8346 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
8347 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
8348 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8349 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
8351 fill_surface(surface, 0xff7f7f7f, 0);
8352 IDirect3DSurface9_Release(surface);
8354 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8355 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8356 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8357 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
8359 hr = IDirect3DDevice9_BeginScene(device);
8360 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8362 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
8363 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
8364 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8365 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8366 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
8367 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8369 hr = IDirect3DDevice9_EndScene(device);
8370 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8372 color = getPixelColor(device, 320, 240);
8373 ok(color_match(color, 0x00363636, 1), "sRGB quad has color 0x%08x, expected 0x00363636.\n", color);
8375 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8376 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8378 IDirect3DTexture9_Release(texture);
8379 refcount = IDirect3DDevice9_Release(device);
8380 ok(!refcount, "Device has %u references left.\n", refcount);
8381 done:
8382 IDirect3D9_Release(d3d);
8383 DestroyWindow(window);
8386 static void test_shademode(void)
8388 IDirect3DVertexBuffer9 *vb_strip;
8389 IDirect3DVertexBuffer9 *vb_list;
8390 IDirect3DVertexShader9 *vs;
8391 IDirect3DPixelShader9 *ps;
8392 IDirect3DDevice9 *device;
8393 DWORD color0, color1;
8394 void *data = NULL;
8395 IDirect3D9 *d3d;
8396 ULONG refcount;
8397 D3DCAPS9 caps;
8398 HWND window;
8399 HRESULT hr;
8400 UINT i;
8401 static const DWORD vs1_code[] =
8403 0xfffe0101, /* vs_1_1 */
8404 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8405 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
8406 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8407 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
8408 0x0000ffff
8410 static const DWORD vs2_code[] =
8412 0xfffe0200, /* vs_2_0 */
8413 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8414 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
8415 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8416 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
8417 0x0000ffff
8419 static const DWORD vs3_code[] =
8421 0xfffe0300, /* vs_3_0 */
8422 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8423 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
8424 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8425 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
8426 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8427 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
8428 0x0000ffff
8430 static const DWORD ps1_code[] =
8432 0xffff0101, /* ps_1_1 */
8433 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
8434 0x0000ffff
8436 static const DWORD ps2_code[] =
8438 0xffff0200, /* ps_2_0 */
8439 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
8440 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8441 0x0000ffff
8443 static const DWORD ps3_code[] =
8445 0xffff0300, /* ps_3_0 */
8446 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
8447 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8448 0x0000ffff
8450 static const struct
8452 struct vec3 position;
8453 DWORD diffuse;
8455 quad_strip[] =
8457 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
8458 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8459 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8460 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
8462 quad_list[] =
8464 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
8465 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8466 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8468 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8469 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8470 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
8472 static const struct test_shader
8474 DWORD version;
8475 const DWORD *code;
8477 novs = {0, NULL},
8478 vs_1 = {D3DVS_VERSION(1, 1), vs1_code},
8479 vs_2 = {D3DVS_VERSION(2, 0), vs2_code},
8480 vs_3 = {D3DVS_VERSION(3, 0), vs3_code},
8481 nops = {0, NULL},
8482 ps_1 = {D3DPS_VERSION(1, 1), ps1_code},
8483 ps_2 = {D3DPS_VERSION(2, 0), ps2_code},
8484 ps_3 = {D3DPS_VERSION(3, 0), ps3_code};
8485 static const struct
8487 const struct test_shader *vs, *ps;
8488 DWORD primtype;
8489 DWORD shademode;
8490 DWORD color0, color1;
8491 BOOL todo;
8493 tests[] =
8495 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8496 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_PHONG, 0x000dca28, 0x000d45c7, FALSE},
8497 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8498 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_PHONG, 0x000dca28, 0x000d45c7, FALSE},
8499 {&novs, &nops, D3DPT_TRIANGLELIST, D3DSHADE_FLAT, 0x00ff0000, 0x000000ff, FALSE},
8500 {&novs, &nops, D3DPT_TRIANGLELIST, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8501 {&vs_1, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8502 {&vs_1, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8503 {&vs_1, &ps_1, D3DPT_TRIANGLELIST, D3DSHADE_FLAT, 0x00ff0000, 0x000000ff, FALSE},
8504 {&vs_1, &ps_1, D3DPT_TRIANGLELIST, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8505 {&novs, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8506 {&vs_1, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8507 {&vs_2, &ps_2, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8508 {&vs_2, &ps_2, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8509 {&vs_3, &ps_3, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, TRUE},
8510 {&vs_3, &ps_3, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8513 window = create_window();
8514 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8515 ok(!!d3d, "Failed to create a D3D object.\n");
8516 if (!(device = create_device(d3d, window, window, TRUE)))
8518 skip("Failed to create a D3D device, skipping tests.\n");
8519 goto done;
8522 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8523 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8524 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
8525 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
8527 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8528 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
8530 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip), 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
8531 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8532 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
8533 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8534 memcpy(data, quad_strip, sizeof(quad_strip));
8535 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
8536 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
8538 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list), 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
8539 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8540 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
8541 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8542 memcpy(data, quad_list, sizeof(quad_list));
8543 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
8544 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
8546 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8547 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
8549 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
8550 * the color fixups we have to do for FLAT shading will be dependent on that. */
8552 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
8554 if (tests[i].vs->version)
8556 if (caps.VertexShaderVersion >= tests[i].vs->version)
8558 hr = IDirect3DDevice9_CreateVertexShader(device, tests[i].vs->code, &vs);
8559 ok(hr == D3D_OK, "Failed to create vertex shader, hr %#x.\n", hr);
8560 hr = IDirect3DDevice9_SetVertexShader(device, vs);
8561 ok(hr == D3D_OK, "Failed to set vertex shader, hr %#x.\n", hr);
8563 else
8565 skip("Shader version unsupported, skipping some tests.\n");
8566 continue;
8569 else
8571 vs = NULL;
8573 if (tests[i].ps->version)
8575 if (caps.PixelShaderVersion >= tests[i].ps->version)
8577 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].ps->code, &ps);
8578 ok(hr == D3D_OK, "Failed to create pixel shader, hr %#x.\n", hr);
8579 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8580 ok(hr == D3D_OK, "Failed to set pixel shader, hr %#x.\n", hr);
8582 else
8584 skip("Shader version unsupported, skipping some tests.\n");
8585 if (vs)
8587 IDirect3DDevice9_SetVertexShader(device, NULL);
8588 IDirect3DVertexShader9_Release(vs);
8590 continue;
8593 else
8595 ps = NULL;
8598 hr = IDirect3DDevice9_SetStreamSource(device, 0,
8599 tests[i].primtype == D3DPT_TRIANGLESTRIP ? vb_strip : vb_list, 0, sizeof(quad_strip[0]));
8600 ok(hr == D3D_OK, "Failed to set stream source, hr %#x.\n", hr);
8602 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
8603 ok(hr == D3D_OK, "Failed to clear, hr %#x.\n", hr);
8605 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shademode);
8606 ok(hr == D3D_OK, "Failed to set shade mode, hr %#x.\n", hr);
8608 hr = IDirect3DDevice9_BeginScene(device);
8609 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8610 hr = IDirect3DDevice9_DrawPrimitive(device, tests[i].primtype, 0, 2);
8611 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8612 hr = IDirect3DDevice9_EndScene(device);
8613 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8615 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
8616 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
8618 /* For D3DSHADE_FLAT it should take the color of the first vertex of
8619 * each triangle. This requires EXT_provoking_vertex or similar
8620 * functionality being available. */
8621 /* PHONG should be the same as GOURAUD, since no hardware implements
8622 * this. */
8623 todo_wine_if (tests[i].todo)
8625 ok(color_match(color0, tests[i].color0, 1), "Test %u shading has color0 %08x, expected %08x.\n",
8626 i, color0, tests[i].color0);
8627 ok(color_match(color1, tests[i].color1, 1), "Test %u shading has color1 %08x, expected %08x.\n",
8628 i, color1, tests[i].color1);
8630 IDirect3DDevice9_SetVertexShader(device, NULL);
8631 IDirect3DDevice9_SetPixelShader(device, NULL);
8633 if (ps)
8634 IDirect3DPixelShader9_Release(ps);
8635 if (vs)
8636 IDirect3DVertexShader9_Release(vs);
8639 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8640 ok(hr == D3D_OK, "Failed to present, hr %#x.\n", hr);
8642 IDirect3DVertexBuffer9_Release(vb_strip);
8643 IDirect3DVertexBuffer9_Release(vb_list);
8644 refcount = IDirect3DDevice9_Release(device);
8645 ok(!refcount, "Device has %u references left.\n", refcount);
8646 done:
8647 IDirect3D9_Release(d3d);
8648 DestroyWindow(window);
8651 static void test_blend(void)
8653 IDirect3DSurface9 *backbuffer, *offscreen;
8654 IDirect3DTexture9 *offscreenTexture;
8655 IDirect3DDevice9 *device;
8656 IDirect3D9 *d3d;
8657 D3DCOLOR color;
8658 ULONG refcount;
8659 HWND window;
8660 HRESULT hr;
8662 static const struct
8664 struct vec3 position;
8665 DWORD diffuse;
8667 quad1[] =
8669 {{-1.0f, -1.0f, 0.1f}, 0x4000ff00},
8670 {{-1.0f, 0.0f, 0.1f}, 0x4000ff00},
8671 {{ 1.0f, -1.0f, 0.1f}, 0x4000ff00},
8672 {{ 1.0f, 0.0f, 0.1f}, 0x4000ff00},
8674 quad2[] =
8676 {{-1.0f, 0.0f, 0.1f}, 0xc00000ff},
8677 {{-1.0f, 1.0f, 0.1f}, 0xc00000ff},
8678 {{ 1.0f, 0.0f, 0.1f}, 0xc00000ff},
8679 {{ 1.0f, 1.0f, 0.1f}, 0xc00000ff},
8681 static const float composite_quad[][5] =
8683 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
8684 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
8685 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
8686 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
8689 window = create_window();
8690 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8691 ok(!!d3d, "Failed to create a D3D object.\n");
8692 if (!(device = create_device(d3d, window, window, TRUE)))
8694 skip("Failed to create a D3D device, skipping tests.\n");
8695 goto done;
8698 /* Clear the render target with alpha = 0.5 */
8699 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x80ff0000, 1.0f, 0);
8700 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8702 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
8703 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8704 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
8706 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8707 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8709 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8710 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8712 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8713 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
8715 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8716 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8717 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8718 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8719 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8720 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8721 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8722 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8723 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8724 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8726 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8727 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8728 hr = IDirect3DDevice9_BeginScene(device);
8729 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8731 /* Draw two quads, one with src alpha blending, one with dest alpha
8732 * blending. */
8733 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8734 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8735 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8736 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8737 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8738 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8740 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
8741 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8742 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
8743 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8744 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8745 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8747 /* Switch to the offscreen buffer, and redo the testing. The offscreen
8748 * render target doesn't have an alpha channel. DESTALPHA and INVDESTALPHA
8749 * "don't work" on render targets without alpha channel, they give
8750 * essentially ZERO and ONE blend factors. */
8751 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8752 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8753 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x80ff0000, 1.0f, 0);
8754 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8756 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8757 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8758 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8759 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8760 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8761 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8763 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
8764 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8765 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
8766 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8767 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8768 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8770 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8771 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8773 /* Render the offscreen texture onto the frame buffer to be able to
8774 * compare it regularly. Disable alpha blending for the final
8775 * composition. */
8776 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8777 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8778 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8779 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8781 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8782 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
8783 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
8784 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8786 hr = IDirect3DDevice9_EndScene(device);
8787 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8789 color = getPixelColor(device, 160, 360);
8790 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
8791 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
8793 color = getPixelColor(device, 160, 120);
8794 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
8795 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
8797 color = getPixelColor(device, 480, 360);
8798 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
8799 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
8801 color = getPixelColor(device, 480, 120);
8802 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
8803 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
8805 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8807 IDirect3DSurface9_Release(backbuffer);
8808 IDirect3DTexture9_Release(offscreenTexture);
8809 IDirect3DSurface9_Release(offscreen);
8810 refcount = IDirect3DDevice9_Release(device);
8811 ok(!refcount, "Device has %u references left.\n", refcount);
8812 done:
8813 IDirect3D9_Release(d3d);
8814 DestroyWindow(window);
8817 static void fixed_function_decl_test(void)
8819 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
8820 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_nocolor, *dcl_positiont;
8821 IDirect3DVertexBuffer9 *vb, *vb2;
8822 IDirect3DDevice9 *device;
8823 BOOL s_ok, ub_ok, f_ok;
8824 DWORD color, size, i;
8825 IDirect3D9 *d3d;
8826 ULONG refcount;
8827 D3DCAPS9 caps;
8828 HWND window;
8829 void *data;
8830 HRESULT hr;
8832 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
8833 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8834 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8835 D3DDECL_END()
8837 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
8838 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8839 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8840 D3DDECL_END()
8842 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
8843 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8844 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8845 D3DDECL_END()
8847 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
8848 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8849 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8850 D3DDECL_END()
8852 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
8853 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8854 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8855 D3DDECL_END()
8857 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
8858 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8859 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8860 D3DDECL_END()
8862 static const D3DVERTEXELEMENT9 decl_elements_nocolor[] = {
8863 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8864 D3DDECL_END()
8866 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
8867 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
8868 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8869 D3DDECL_END()
8871 static const struct
8873 struct vec3 position;
8874 DWORD diffuse;
8876 quad1[] = /* D3DCOLOR */
8878 {{-1.0f, -1.0f, 0.1f}, 0x00ffff00},
8879 {{-1.0f, 0.0f, 0.1f}, 0x00ffff00},
8880 {{ 0.0f, -1.0f, 0.1f}, 0x00ffff00},
8881 {{ 0.0f, 0.0f, 0.1f}, 0x00ffff00},
8883 quad2[] = /* UBYTE4N */
8885 {{-1.0f, 0.0f, 0.1f}, 0x00ffff00},
8886 {{-1.0f, 1.0f, 0.1f}, 0x00ffff00},
8887 {{ 0.0f, 0.0f, 0.1f}, 0x00ffff00},
8888 {{ 0.0f, 1.0f, 0.1f}, 0x00ffff00},
8890 static const struct
8892 struct vec3 position;
8893 struct { unsigned short x, y, z, w; } color;
8895 quad3[] = /* USHORT4N */
8897 {{0.0f, -1.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8898 {{0.0f, 0.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8899 {{1.0f, -1.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8900 {{1.0f, 0.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8902 static const struct
8904 struct vec3 position;
8905 struct vec4 color;
8907 quad4[] =
8909 {{0.0f, 0.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8910 {{0.0f, 1.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8911 {{1.0f, 0.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8912 {{1.0f, 1.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8914 static const DWORD colors[] =
8916 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8917 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8918 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8919 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8920 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8921 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8922 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8923 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8924 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8925 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8926 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8927 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8928 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8929 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8930 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8931 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8933 static const float quads[] =
8935 -1.0f, -1.0f, 0.1f,
8936 -1.0f, 0.0f, 0.1f,
8937 0.0f, -1.0f, 0.1f,
8938 0.0f, 0.0f, 0.1f,
8940 0.0f, -1.0f, 0.1f,
8941 0.0f, 0.0f, 0.1f,
8942 1.0f, -1.0f, 0.1f,
8943 1.0f, 0.0f, 0.1f,
8945 0.0f, 0.0f, 0.1f,
8946 0.0f, 1.0f, 0.1f,
8947 1.0f, 0.0f, 0.1f,
8948 1.0f, 1.0f, 0.1f,
8950 -1.0f, 0.0f, 0.1f,
8951 -1.0f, 1.0f, 0.1f,
8952 0.0f, 0.0f, 0.1f,
8953 0.0f, 1.0f, 0.1f,
8955 static const struct
8957 struct vec4 position;
8958 DWORD diffuse;
8960 quad_transformed[] =
8962 {{ 90.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
8963 {{570.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
8964 {{ 90.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
8965 {{570.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
8968 window = create_window();
8969 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8970 ok(!!d3d, "Failed to create a D3D object.\n");
8971 if (!(device = create_device(d3d, window, window, TRUE)))
8973 skip("Failed to create a D3D device, skipping tests.\n");
8974 goto done;
8977 memset(&caps, 0, sizeof(caps));
8978 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8979 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
8981 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
8982 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8984 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
8985 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8986 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
8987 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
8988 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
8989 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8990 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
8991 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
8992 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8993 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
8994 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8995 } else {
8996 trace("D3DDTCAPS_UBYTE4N not supported\n");
8997 dcl_ubyte_2 = NULL;
8998 dcl_ubyte = NULL;
9000 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
9001 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
9002 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_nocolor, &dcl_nocolor);
9003 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
9004 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
9005 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
9007 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
9008 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
9009 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9010 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9012 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9013 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
9015 hr = IDirect3DDevice9_BeginScene(device);
9016 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9018 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
9019 if (dcl_color)
9021 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
9022 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9023 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9024 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9027 /* Tests with non-standard fixed function types fail on the refrast. The
9028 * ATI driver partially accepts them, the NVIDIA driver accepts them all.
9029 * All those differences even though we're using software vertex
9030 * processing. Doh! */
9031 if (dcl_ubyte)
9033 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
9034 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9035 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9036 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9037 ub_ok = SUCCEEDED(hr);
9040 if (dcl_short)
9042 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
9043 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9044 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
9045 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9046 s_ok = SUCCEEDED(hr);
9049 if (dcl_float)
9051 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
9052 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9053 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
9054 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9055 f_ok = SUCCEEDED(hr);
9058 hr = IDirect3DDevice9_EndScene(device);
9059 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9061 if(dcl_short) {
9062 color = getPixelColor(device, 480, 360);
9063 ok(color == 0x000000ff || !s_ok,
9064 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
9066 if(dcl_ubyte) {
9067 color = getPixelColor(device, 160, 120);
9068 ok(color == 0x0000ffff || !ub_ok,
9069 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
9071 if(dcl_color) {
9072 color = getPixelColor(device, 160, 360);
9073 ok(color == 0x00ffff00,
9074 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
9076 if(dcl_float) {
9077 color = getPixelColor(device, 480, 120);
9078 ok(color == 0x00ff0000 || !f_ok,
9079 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
9081 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9083 /* The following test with vertex buffers doesn't serve to find out new
9084 * information from windows. It is a plain regression test because wined3d
9085 * uses different codepaths for attribute conversion with vertex buffers.
9086 * It makes sure that the vertex buffer one works, while the above tests
9087 * whether the immediate mode code works. */
9088 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
9089 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
9090 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9091 hr = IDirect3DDevice9_BeginScene(device);
9092 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9094 if (dcl_color)
9096 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
9097 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
9098 memcpy(data, quad1, sizeof(quad1));
9099 hr = IDirect3DVertexBuffer9_Unlock(vb);
9100 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
9101 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
9102 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9103 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
9104 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
9105 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9106 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9109 if (dcl_ubyte)
9111 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
9112 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
9113 memcpy(data, quad2, sizeof(quad2));
9114 hr = IDirect3DVertexBuffer9_Unlock(vb);
9115 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
9116 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
9117 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9118 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
9119 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
9120 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9121 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9122 ub_ok = SUCCEEDED(hr);
9125 if (dcl_short)
9127 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
9128 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
9129 memcpy(data, quad3, sizeof(quad3));
9130 hr = IDirect3DVertexBuffer9_Unlock(vb);
9131 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
9132 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
9133 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9134 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
9135 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
9136 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9137 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9138 s_ok = SUCCEEDED(hr);
9141 if (dcl_float)
9143 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
9144 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
9145 memcpy(data, quad4, sizeof(quad4));
9146 hr = IDirect3DVertexBuffer9_Unlock(vb);
9147 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
9148 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
9149 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9150 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
9151 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
9152 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9153 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9154 f_ok = SUCCEEDED(hr);
9157 hr = IDirect3DDevice9_EndScene(device);
9158 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9160 if(dcl_short) {
9161 color = getPixelColor(device, 480, 360);
9162 ok(color == 0x000000ff || !s_ok,
9163 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
9165 if(dcl_ubyte) {
9166 color = getPixelColor(device, 160, 120);
9167 ok(color == 0x0000ffff || !ub_ok,
9168 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
9170 if(dcl_color) {
9171 color = getPixelColor(device, 160, 360);
9172 ok(color == 0x00ffff00,
9173 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
9175 if(dcl_float) {
9176 color = getPixelColor(device, 480, 120);
9177 ok(color == 0x00ff0000 || !f_ok,
9178 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
9180 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9182 /* Test with no diffuse color attribute. */
9183 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9184 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9186 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_nocolor);
9187 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9188 hr = IDirect3DDevice9_BeginScene(device);
9189 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9190 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quads, sizeof(float) * 3);
9191 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9192 hr = IDirect3DDevice9_EndScene(device);
9193 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9195 color = getPixelColor(device, 160, 360);
9196 ok(color == 0x00ffffff, "Got unexpected color 0x%08x in the no color attribute test.\n", color);
9198 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9200 /* Test what happens with specular lighting enabled and no specular color attribute. */
9201 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
9202 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
9203 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9204 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
9205 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#x.\n", hr);
9206 hr = IDirect3DDevice9_BeginScene(device);
9207 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9209 if (dcl_color)
9211 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
9212 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9213 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9214 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9216 if (dcl_ubyte)
9218 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
9219 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9220 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9221 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9222 ub_ok = SUCCEEDED(hr);
9224 if (dcl_short)
9226 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
9227 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9228 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
9229 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9230 s_ok = SUCCEEDED(hr);
9232 if (dcl_float)
9234 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
9235 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9236 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
9237 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9238 f_ok = SUCCEEDED(hr);
9241 hr = IDirect3DDevice9_EndScene(device);
9242 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9243 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARENABLE, FALSE);
9244 ok(SUCCEEDED(hr), "Failed to disable specular lighting, hr %#x.\n", hr);
9246 if (dcl_short)
9248 color = getPixelColor(device, 480, 360);
9249 ok(color == 0x000000ff || !s_ok,
9250 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff.\n", color);
9252 if (dcl_ubyte)
9254 color = getPixelColor(device, 160, 120);
9255 ok(color == 0x0000ffff || !ub_ok,
9256 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff.\n", color);
9258 if (dcl_color)
9260 color = getPixelColor(device, 160, 360);
9261 ok(color == 0x00ffff00,
9262 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00.\n", color);
9264 if (dcl_float)
9266 color = getPixelColor(device, 480, 120);
9267 ok(color == 0x00ff0000 || !f_ok,
9268 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000.\n", color);
9270 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9272 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
9273 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9274 memcpy(data, quad_transformed, sizeof(quad_transformed));
9275 hr = IDirect3DVertexBuffer9_Unlock(vb);
9276 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
9278 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
9279 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
9281 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9282 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9284 hr = IDirect3DDevice9_BeginScene(device);
9285 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9286 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
9287 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
9288 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9289 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9290 hr = IDirect3DDevice9_EndScene(device);
9291 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9293 color = getPixelColor(device, 88, 108);
9294 ok(color == 0x000000ff,
9295 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
9296 color = getPixelColor(device, 92, 108);
9297 ok(color == 0x000000ff,
9298 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
9299 color = getPixelColor(device, 88, 112);
9300 ok(color == 0x000000ff,
9301 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
9302 color = getPixelColor(device, 92, 112);
9303 ok(color == 0x00ffff00,
9304 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
9306 color = getPixelColor(device, 568, 108);
9307 ok(color == 0x000000ff,
9308 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
9309 color = getPixelColor(device, 572, 108);
9310 ok(color == 0x000000ff,
9311 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
9312 color = getPixelColor(device, 568, 112);
9313 ok(color == 0x00ffff00,
9314 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
9315 color = getPixelColor(device, 572, 112);
9316 ok(color == 0x000000ff,
9317 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
9319 color = getPixelColor(device, 88, 298);
9320 ok(color == 0x000000ff,
9321 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
9322 color = getPixelColor(device, 92, 298);
9323 ok(color == 0x00ffff00,
9324 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
9325 color = getPixelColor(device, 88, 302);
9326 ok(color == 0x000000ff,
9327 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
9328 color = getPixelColor(device, 92, 302);
9329 ok(color == 0x000000ff,
9330 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
9332 color = getPixelColor(device, 568, 298);
9333 ok(color == 0x00ffff00,
9334 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
9335 color = getPixelColor(device, 572, 298);
9336 ok(color == 0x000000ff,
9337 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
9338 color = getPixelColor(device, 568, 302);
9339 ok(color == 0x000000ff,
9340 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
9341 color = getPixelColor(device, 572, 302);
9342 ok(color == 0x000000ff,
9343 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
9345 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9347 /* This test is pointless without those two declarations: */
9348 if((!dcl_color_2) || (!dcl_ubyte_2)) {
9349 skip("color-ubyte switching test declarations aren't supported\n");
9350 goto out;
9353 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
9354 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9355 memcpy(data, quads, sizeof(quads));
9356 hr = IDirect3DVertexBuffer9_Unlock(vb);
9357 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
9358 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
9359 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9360 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9361 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
9362 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9363 memcpy(data, colors, sizeof(colors));
9364 hr = IDirect3DVertexBuffer9_Unlock(vb2);
9365 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
9367 for(i = 0; i < 2; i++) {
9368 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9369 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9371 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
9372 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
9373 if(i == 0) {
9374 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
9375 } else {
9376 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
9378 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
9380 hr = IDirect3DDevice9_BeginScene(device);
9381 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9383 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
9384 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9385 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9386 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9387 ub_ok = SUCCEEDED(hr);
9389 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
9390 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9391 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
9392 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9394 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
9395 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9396 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
9397 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9398 ub_ok = (SUCCEEDED(hr) && ub_ok);
9400 hr = IDirect3DDevice9_EndScene(device);
9401 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9403 if(i == 0) {
9404 color = getPixelColor(device, 480, 360);
9405 ok(color == 0x00ff0000,
9406 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
9407 color = getPixelColor(device, 160, 120);
9408 ok(color == 0x00ffffff,
9409 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
9410 color = getPixelColor(device, 160, 360);
9411 ok(color == 0x000000ff || !ub_ok,
9412 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
9413 color = getPixelColor(device, 480, 120);
9414 ok(color == 0x000000ff || !ub_ok,
9415 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
9416 } else {
9417 color = getPixelColor(device, 480, 360);
9418 ok(color == 0x000000ff,
9419 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
9420 color = getPixelColor(device, 160, 120);
9421 ok(color == 0x00ffffff,
9422 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
9423 color = getPixelColor(device, 160, 360);
9424 ok(color == 0x00ff0000 || !ub_ok,
9425 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
9426 color = getPixelColor(device, 480, 120);
9427 ok(color == 0x00ff0000 || !ub_ok,
9428 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
9430 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9433 IDirect3DVertexBuffer9_Release(vb2);
9434 out:
9435 IDirect3DVertexBuffer9_Release(vb);
9436 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
9437 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
9438 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
9439 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
9440 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
9441 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
9442 IDirect3DVertexDeclaration9_Release(dcl_nocolor);
9443 IDirect3DVertexDeclaration9_Release(dcl_positiont);
9444 refcount = IDirect3DDevice9_Release(device);
9445 ok(!refcount, "Device has %u references left.\n", refcount);
9446 done:
9447 IDirect3D9_Release(d3d);
9448 DestroyWindow(window);
9451 static void test_vshader_float16(void)
9453 IDirect3DVertexDeclaration9 *vdecl = NULL;
9454 IDirect3DVertexBuffer9 *buffer = NULL;
9455 IDirect3DVertexShader9 *shader;
9456 IDirect3DDevice9 *device;
9457 IDirect3D9 *d3d;
9458 ULONG refcount;
9459 D3DCAPS9 caps;
9460 DWORD color;
9461 HWND window;
9462 void *data;
9463 HRESULT hr;
9465 static const D3DVERTEXELEMENT9 decl_elements[] =
9467 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9468 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9469 D3DDECL_END()
9471 static const DWORD shader_code[] =
9473 0xfffe0101, /* vs_1_1 */
9474 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9475 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
9476 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
9477 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
9478 0x0000ffff,
9480 static const struct vertex_float16color
9482 float x, y, z;
9483 DWORD c1, c2;
9485 quad[] =
9487 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
9488 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
9489 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
9490 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
9492 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
9493 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
9494 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
9495 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
9497 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
9498 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
9499 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
9500 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
9502 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
9503 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
9504 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
9505 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
9508 window = create_window();
9509 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9510 ok(!!d3d, "Failed to create a D3D object.\n");
9511 if (!(device = create_device(d3d, window, window, TRUE)))
9513 skip("Failed to create a D3D device, skipping tests.\n");
9514 goto done;
9517 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9518 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
9519 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
9521 skip("No vs_3_0 support, skipping tests.\n");
9522 IDirect3DDevice9_Release(device);
9523 goto done;
9526 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff102030, 1.0f, 0);
9527 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9529 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
9530 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
9531 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9532 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9533 hr = IDirect3DDevice9_SetVertexShader(device, shader);
9534 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9536 hr = IDirect3DDevice9_BeginScene(device);
9537 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9538 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
9539 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9540 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
9541 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9542 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
9543 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9544 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
9545 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9546 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
9547 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9548 hr = IDirect3DDevice9_EndScene(device);
9549 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9551 color = getPixelColor(device, 480, 360);
9552 ok(color == 0x00ff0000,
9553 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
9554 color = getPixelColor(device, 160, 120);
9555 ok(color == 0x00000000,
9556 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
9557 color = getPixelColor(device, 160, 360);
9558 ok(color == 0x0000ff00,
9559 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
9560 color = getPixelColor(device, 480, 120);
9561 ok(color == 0x000000ff,
9562 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
9563 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9565 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
9566 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9568 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
9569 D3DPOOL_MANAGED, &buffer, NULL);
9570 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
9571 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
9572 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
9573 memcpy(data, quad, sizeof(quad));
9574 hr = IDirect3DVertexBuffer9_Unlock(buffer);
9575 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
9576 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
9577 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
9579 hr = IDirect3DDevice9_BeginScene(device);
9580 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9581 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9582 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9583 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
9584 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9585 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
9586 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9587 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
9588 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9589 hr = IDirect3DDevice9_EndScene(device);
9590 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9592 color = getPixelColor(device, 480, 360);
9593 ok(color == 0x00ff0000,
9594 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
9595 color = getPixelColor(device, 160, 120);
9596 ok(color == 0x00000000,
9597 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
9598 color = getPixelColor(device, 160, 360);
9599 ok(color == 0x0000ff00,
9600 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
9601 color = getPixelColor(device, 480, 120);
9602 ok(color == 0x000000ff,
9603 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
9604 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9606 IDirect3DVertexDeclaration9_Release(vdecl);
9607 IDirect3DVertexShader9_Release(shader);
9608 IDirect3DVertexBuffer9_Release(buffer);
9609 refcount = IDirect3DDevice9_Release(device);
9610 ok(!refcount, "Device has %u references left.\n", refcount);
9611 done:
9612 IDirect3D9_Release(d3d);
9613 DestroyWindow(window);
9616 static void conditional_np2_repeat_test(void)
9618 IDirect3DTexture9 *texture;
9619 IDirect3DDevice9 *device;
9620 D3DLOCKED_RECT rect;
9621 unsigned int x, y;
9622 DWORD *dst, color;
9623 IDirect3D9 *d3d;
9624 ULONG refcount;
9625 D3DCAPS9 caps;
9626 HWND window;
9627 HRESULT hr;
9629 static const float quad[] =
9631 -1.0f, -1.0f, 0.1f, -0.2f, -0.2f,
9632 -1.0f, 1.0f, 0.1f, -0.2f, 1.2f,
9633 1.0f, -1.0f, 0.1f, 1.2f, -0.2f,
9634 1.0f, 1.0f, 0.1f, 1.2f, 1.2f,
9637 window = create_window();
9638 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9639 ok(!!d3d, "Failed to create a D3D object.\n");
9640 if (!(device = create_device(d3d, window, window, TRUE)))
9642 skip("Failed to create a D3D device, skipping tests.\n");
9643 goto done;
9646 memset(&caps, 0, sizeof(caps));
9647 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9648 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
9649 if (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)
9651 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
9652 ok(caps.TextureCaps & D3DPTEXTURECAPS_POW2,
9653 "Card has conditional NP2 support without power of two restriction set\n");
9655 else if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
9657 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
9658 IDirect3DDevice9_Release(device);
9659 goto done;
9661 else
9663 skip("Card has unconditional NP2 support, skipping conditional NP2 tests\n");
9664 IDirect3DDevice9_Release(device);
9665 goto done;
9668 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
9669 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9671 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9672 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9674 memset(&rect, 0, sizeof(rect));
9675 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
9676 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9677 for(y = 0; y < 10; y++) {
9678 for(x = 0; x < 10; x++) {
9679 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
9680 if(x == 0 || x == 9 || y == 0 || y == 9) {
9681 *dst = 0x00ff0000;
9682 } else {
9683 *dst = 0x000000ff;
9687 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9688 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9690 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
9691 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9692 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9693 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
9694 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
9695 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
9696 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
9697 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
9698 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9699 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
9701 hr = IDirect3DDevice9_BeginScene(device);
9702 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9703 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9704 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9705 hr = IDirect3DDevice9_EndScene(device);
9706 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9708 color = getPixelColor(device, 1, 1);
9709 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
9710 color = getPixelColor(device, 639, 479);
9711 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
9713 color = getPixelColor(device, 135, 101);
9714 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
9715 color = getPixelColor(device, 140, 101);
9716 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
9717 color = getPixelColor(device, 135, 105);
9718 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
9719 color = getPixelColor(device, 140, 105);
9720 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
9722 color = getPixelColor(device, 135, 376);
9723 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
9724 color = getPixelColor(device, 140, 376);
9725 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
9726 color = getPixelColor(device, 135, 379);
9727 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
9728 color = getPixelColor(device, 140, 379);
9729 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
9731 color = getPixelColor(device, 500, 101);
9732 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
9733 color = getPixelColor(device, 504, 101);
9734 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
9735 color = getPixelColor(device, 500, 105);
9736 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
9737 color = getPixelColor(device, 504, 105);
9738 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
9740 color = getPixelColor(device, 500, 376);
9741 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
9742 color = getPixelColor(device, 504, 376);
9743 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
9744 color = getPixelColor(device, 500, 380);
9745 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
9746 color = getPixelColor(device, 504, 380);
9747 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
9749 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9751 IDirect3DTexture9_Release(texture);
9752 refcount = IDirect3DDevice9_Release(device);
9753 ok(!refcount, "Device has %u references left.\n", refcount);
9754 done:
9755 IDirect3D9_Release(d3d);
9756 DestroyWindow(window);
9759 static void vface_register_test(void)
9761 IDirect3DSurface9 *surface, *backbuffer;
9762 IDirect3DVertexShader9 *vshader;
9763 IDirect3DPixelShader9 *shader;
9764 IDirect3DTexture9 *texture;
9765 IDirect3DDevice9 *device;
9766 IDirect3D9 *d3d;
9767 ULONG refcount;
9768 D3DCAPS9 caps;
9769 DWORD color;
9770 HWND window;
9771 HRESULT hr;
9773 static const DWORD shader_code[] =
9775 0xffff0300, /* ps_3_0 */
9776 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9777 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
9778 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
9779 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
9780 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
9781 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
9782 0x0000ffff /* END */
9784 static const DWORD vshader_code[] =
9786 0xfffe0300, /* vs_3_0 */
9787 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9788 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
9789 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
9790 0x0000ffff /* end */
9792 static const float quad[] =
9794 -1.0f, -1.0f, 0.1f,
9795 1.0f, -1.0f, 0.1f,
9796 -1.0f, 0.0f, 0.1f,
9798 1.0f, -1.0f, 0.1f,
9799 1.0f, 0.0f, 0.1f,
9800 -1.0f, 0.0f, 0.1f,
9802 -1.0f, 0.0f, 0.1f,
9803 -1.0f, 1.0f, 0.1f,
9804 1.0f, 0.0f, 0.1f,
9806 1.0f, 0.0f, 0.1f,
9807 -1.0f, 1.0f, 0.1f,
9808 1.0f, 1.0f, 0.1f,
9810 static const float blit[] =
9812 0.0f, -1.0f, 0.1f, 0.0f, 0.0f,
9813 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
9814 0.0f, 1.0f, 0.1f, 0.0f, 1.0f,
9815 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
9818 window = create_window();
9819 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9820 ok(!!d3d, "Failed to create a D3D object.\n");
9821 if (!(device = create_device(d3d, window, window, TRUE)))
9823 skip("Failed to create a D3D device, skipping tests.\n");
9824 goto done;
9827 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9828 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
9829 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
9831 skip("No shader model 3 support, skipping tests.\n");
9832 IDirect3DDevice9_Release(device);
9833 goto done;
9836 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
9837 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9838 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
9839 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
9840 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
9841 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9842 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
9843 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
9844 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
9845 ok(SUCCEEDED(hr), "Failed to set cull mode, hr %#x.\n", hr);
9846 hr = IDirect3DDevice9_SetPixelShader(device, shader);
9847 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
9848 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
9849 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9850 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9851 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
9852 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9853 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
9855 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
9856 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9858 hr = IDirect3DDevice9_BeginScene(device);
9859 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9861 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
9862 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
9863 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
9864 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9865 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9866 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
9867 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9868 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9869 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
9870 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
9871 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9873 /* Blit the texture onto the back buffer to make it visible */
9874 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9875 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
9876 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9877 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9878 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
9879 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
9880 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9881 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
9882 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9883 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
9884 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9885 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9886 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
9887 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9889 hr = IDirect3DDevice9_EndScene(device);
9890 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9892 color = getPixelColor(device, 160, 360);
9893 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
9894 color = getPixelColor(device, 160, 120);
9895 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
9896 color = getPixelColor(device, 480, 360);
9897 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
9898 color = getPixelColor(device, 480, 120);
9899 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
9900 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9901 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
9903 IDirect3DPixelShader9_Release(shader);
9904 IDirect3DVertexShader9_Release(vshader);
9905 IDirect3DSurface9_Release(surface);
9906 IDirect3DSurface9_Release(backbuffer);
9907 IDirect3DTexture9_Release(texture);
9908 refcount = IDirect3DDevice9_Release(device);
9909 ok(!refcount, "Device has %u references left.\n", refcount);
9910 done:
9911 IDirect3D9_Release(d3d);
9912 DestroyWindow(window);
9915 static void fixed_function_bumpmap_test(void)
9917 IDirect3DVertexDeclaration9 *vertex_declaration;
9918 IDirect3DTexture9 *texture, *tex1, *tex2;
9919 D3DLOCKED_RECT locked_rect;
9920 IDirect3DDevice9 *device;
9921 BOOL L6V5U5_supported;
9922 float scale, offset;
9923 IDirect3D9 *d3d;
9924 unsigned int i;
9925 D3DCOLOR color;
9926 ULONG refcount;
9927 D3DCAPS9 caps;
9928 HWND window;
9929 HRESULT hr;
9931 static const float quad[][7] =
9933 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
9934 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
9935 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
9936 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
9938 static const D3DVERTEXELEMENT9 decl_elements[] =
9940 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9941 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9942 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
9943 D3DDECL_END()
9945 /* use asymmetric matrix to test loading */
9946 static const float bumpenvmat[4] = {0.0f, 0.5f, -0.5f, 0.0f};
9948 window = create_window();
9949 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9950 ok(!!d3d, "Failed to create a D3D object.\n");
9951 if (!(device = create_device(d3d, window, window, TRUE)))
9953 skip("Failed to create a D3D device, skipping tests.\n");
9954 goto done;
9957 memset(&caps, 0, sizeof(caps));
9958 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9959 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
9960 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP))
9962 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
9963 IDirect3DDevice9_Release(device);
9964 goto done;
9967 /* This check is disabled, some Windows drivers do not handle
9968 * D3DUSAGE_QUERY_LEGACYBUMPMAP properly. They report that it is not
9969 * supported, but after that bump mapping works properly. So just test if
9970 * the format is generally supported, and check the BUMPENVMAP flag. */
9971 L6V5U5_supported = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
9972 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_L6V5U5));
9973 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
9974 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_V8U8)))
9976 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
9977 IDirect3DDevice9_Release(device);
9978 return;
9981 /* Generate the textures */
9982 generate_bumpmap_textures(device);
9984 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
9985 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9986 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
9987 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9988 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
9989 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9990 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
9991 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9993 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
9994 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9995 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
9996 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9997 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
9998 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
10000 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10001 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
10002 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10003 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
10004 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
10005 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
10007 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
10008 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
10010 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10011 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
10013 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff00ff, 1.0f, 0);
10014 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
10016 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
10017 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
10018 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
10019 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
10021 hr = IDirect3DDevice9_BeginScene(device);
10022 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
10024 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
10025 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
10027 hr = IDirect3DDevice9_EndScene(device);
10028 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
10030 color = getPixelColor(device, 240, 60);
10031 ok(color_match(color, 0x005ea000, 4), "Got unexpected color 0x%08x.\n", color);
10032 color = getPixelColor(device, 400, 60);
10033 ok(color_match(color, 0x009ea000, 4), "Got unexpected color 0x%08x.\n", color);
10034 color = getPixelColor(device, 80, 180);
10035 ok(color_match(color, 0x005ea000, 4), "Got unexpected color 0x%08x.\n", color);
10036 color = getPixelColor(device, 560, 180);
10037 ok(color_match(color, 0x009ea000, 4), "Got unexpected color 0x%08x.\n", color);
10038 color = getPixelColor(device, 80, 300);
10039 ok(color_match(color, 0x005e6000, 4), "Got unexpected color 0x%08x.\n", color);
10040 color = getPixelColor(device, 560, 300);
10041 ok(color_match(color, 0x009e6000, 4), "Got unexpected color 0x%08x.\n", color);
10042 color = getPixelColor(device, 240, 420);
10043 ok(color_match(color, 0x005e6000, 4), "Got unexpected color 0x%08x.\n", color);
10044 color = getPixelColor(device, 400, 420);
10045 ok(color_match(color, 0x009e6000, 4), "Got unexpected color 0x%08x.\n", color);
10046 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10047 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10049 for(i = 0; i < 2; i++) {
10050 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
10051 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
10052 IDirect3DTexture9_Release(texture); /* For the GetTexture */
10053 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
10054 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
10055 IDirect3DTexture9_Release(texture); /* To destroy it */
10058 if (!L6V5U5_supported || !(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE))
10060 skip("L6V5U5 / D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping tests.\n");
10061 IDirect3DVertexDeclaration9_Release(vertex_declaration);
10062 IDirect3DDevice9_Release(device);
10063 goto done;
10066 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10067 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10068 /* This test only tests the luminance part. The bumpmapping part was already tested above and
10069 * would only make this test more complicated
10071 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
10072 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
10073 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
10074 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
10076 memset(&locked_rect, 0, sizeof(locked_rect));
10077 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
10078 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10079 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
10080 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
10081 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10083 memset(&locked_rect, 0, sizeof(locked_rect));
10084 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
10085 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10086 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
10087 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
10088 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10090 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
10091 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
10092 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
10093 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
10095 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
10096 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
10097 scale = 2.0;
10098 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
10099 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
10100 offset = 0.1;
10101 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
10102 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
10104 hr = IDirect3DDevice9_BeginScene(device);
10105 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10106 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
10107 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10108 hr = IDirect3DDevice9_EndScene(device);
10109 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10111 color = getPixelColor(device, 320, 240);
10112 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
10113 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
10114 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
10116 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
10117 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10118 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10120 /* Check a result scale factor > 1.0 */
10121 scale = 10;
10122 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
10123 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
10124 offset = 10;
10125 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
10126 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
10128 hr = IDirect3DDevice9_BeginScene(device);
10129 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10130 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
10131 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10132 hr = IDirect3DDevice9_EndScene(device);
10133 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10135 color = getPixelColor(device, 320, 240);
10136 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
10137 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10138 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10140 /* Check clamping in the scale factor calculation */
10141 scale = 1000;
10142 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
10143 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
10144 offset = -1;
10145 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
10146 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
10148 hr = IDirect3DDevice9_BeginScene(device);
10149 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10150 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
10151 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10152 hr = IDirect3DDevice9_EndScene(device);
10153 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10155 color = getPixelColor(device, 320, 240);
10156 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
10157 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10158 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10160 IDirect3DTexture9_Release(tex1);
10161 IDirect3DTexture9_Release(tex2);
10162 IDirect3DVertexDeclaration9_Release(vertex_declaration);
10163 refcount = IDirect3DDevice9_Release(device);
10164 ok(!refcount, "Device has %u references left.\n", refcount);
10165 done:
10166 IDirect3D9_Release(d3d);
10167 DestroyWindow(window);
10170 static void stencil_cull_test(void)
10172 IDirect3DDevice9 *device;
10173 IDirect3D9 *d3d;
10174 ULONG refcount;
10175 D3DCAPS9 caps;
10176 HWND window;
10177 HRESULT hr;
10178 static const float quad1[] =
10180 -1.0, -1.0, 0.1,
10181 0.0, -1.0, 0.1,
10182 -1.0, 0.0, 0.1,
10183 0.0, 0.0, 0.1,
10185 static const float quad2[] =
10187 0.0, -1.0, 0.1,
10188 1.0, -1.0, 0.1,
10189 0.0, 0.0, 0.1,
10190 1.0, 0.0, 0.1,
10192 static const float quad3[] =
10194 0.0, 0.0, 0.1,
10195 1.0, 0.0, 0.1,
10196 0.0, 1.0, 0.1,
10197 1.0, 1.0, 0.1,
10199 static const float quad4[] =
10201 -1.0, 0.0, 0.1,
10202 0.0, 0.0, 0.1,
10203 -1.0, 1.0, 0.1,
10204 0.0, 1.0, 0.1,
10206 struct
10208 struct vec3 position;
10209 DWORD diffuse;
10211 painter[] =
10213 {{-1.0f, -1.0f, 0.0f}, 0x00000000},
10214 {{ 1.0f, -1.0f, 0.0f}, 0x00000000},
10215 {{-1.0f, 1.0f, 0.0f}, 0x00000000},
10216 {{ 1.0f, 1.0f, 0.0f}, 0x00000000},
10218 static const WORD indices_cw[] = {0, 1, 3};
10219 static const WORD indices_ccw[] = {0, 2, 3};
10220 unsigned int i;
10221 DWORD color;
10223 window = create_window();
10224 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10225 ok(!!d3d, "Failed to create a D3D object.\n");
10226 if (!(device = create_device(d3d, window, window, TRUE)))
10228 skip("Cannot create a device with a D24S8 stencil buffer.\n");
10229 DestroyWindow(window);
10230 IDirect3D9_Release(d3d);
10231 return;
10233 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10234 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
10235 if (!(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED))
10237 skip("No two sided stencil support\n");
10238 goto cleanup;
10241 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
10242 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10243 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10244 ok(SUCCEEDED(hr), "Failed to set FVF,hr %#x.\n", hr);
10246 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10247 ok(hr == D3D_OK, "Failed to disable Z test, %#x.\n", hr);
10248 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10249 ok(hr == D3D_OK, "Failed to disable lighting, %#x.\n", hr);
10250 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
10251 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10252 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
10253 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10254 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
10255 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10256 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
10257 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10259 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
10260 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10261 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
10262 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10263 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
10264 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10266 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
10267 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10268 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
10269 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10271 /* First pass: Fill the stencil buffer with some values... */
10272 hr = IDirect3DDevice9_BeginScene(device);
10273 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10275 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
10276 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10277 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10278 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
10279 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10280 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10281 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
10282 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10284 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
10285 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10286 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
10287 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10288 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10289 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
10290 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10291 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10292 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
10293 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10295 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
10296 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10297 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10298 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
10299 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10300 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10301 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
10302 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10304 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
10305 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10306 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10307 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
10308 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10309 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10310 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
10311 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10313 hr = IDirect3DDevice9_EndScene(device);
10314 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10316 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
10317 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10318 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
10319 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10320 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
10321 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10322 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
10323 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10324 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
10325 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10326 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
10327 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10329 /* 2nd pass: Make the stencil values visible */
10330 hr = IDirect3DDevice9_BeginScene(device);
10331 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10332 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10333 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
10334 for (i = 0; i < 16; ++i)
10336 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
10337 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10339 painter[0].diffuse = (i * 16); /* Creates shades of blue */
10340 painter[1].diffuse = (i * 16);
10341 painter[2].diffuse = (i * 16);
10342 painter[3].diffuse = (i * 16);
10343 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
10344 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10346 hr = IDirect3DDevice9_EndScene(device);
10347 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10349 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
10350 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10352 color = getPixelColor(device, 160, 420);
10353 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
10354 color = getPixelColor(device, 160, 300);
10355 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
10357 color = getPixelColor(device, 480, 420);
10358 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
10359 color = getPixelColor(device, 480, 300);
10360 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
10362 color = getPixelColor(device, 160, 180);
10363 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
10364 color = getPixelColor(device, 160, 60);
10365 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
10367 color = getPixelColor(device, 480, 180);
10368 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
10369 color = getPixelColor(device, 480, 60);
10370 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
10372 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10373 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10375 cleanup:
10376 refcount = IDirect3DDevice9_Release(device);
10377 ok(!refcount, "Device has %u references left.\n", refcount);
10378 IDirect3D9_Release(d3d);
10379 DestroyWindow(window);
10382 static void test_fragment_coords(void)
10384 IDirect3DSurface9 *surface = NULL, *backbuffer;
10385 IDirect3DPixelShader9 *shader, *shader_frac;
10386 IDirect3DVertexShader9 *vshader;
10387 IDirect3DDevice9 *device;
10388 D3DLOCKED_RECT lr;
10389 IDirect3D9 *d3d;
10390 ULONG refcount;
10391 D3DCAPS9 caps;
10392 DWORD color;
10393 HWND window;
10394 HRESULT hr;
10395 DWORD *pos;
10397 static const DWORD shader_code[] =
10399 0xffff0300, /* ps_3_0 */
10400 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
10401 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
10402 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
10403 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
10404 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
10405 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
10406 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
10407 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
10408 0x0000ffff /* end */
10410 static const DWORD shader_frac_code[] =
10412 0xffff0300, /* ps_3_0 */
10413 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
10414 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
10415 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
10416 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
10417 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
10418 0x0000ffff /* end */
10420 static const DWORD vshader_code[] =
10422 0xfffe0300, /* vs_3_0 */
10423 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10424 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
10425 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
10426 0x0000ffff /* end */
10428 static const float quad[] =
10430 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
10431 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
10432 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
10433 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
10435 float constant[4] = {1.0, 0.0, 320, 240};
10437 window = create_window();
10438 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10439 ok(!!d3d, "Failed to create a D3D object.\n");
10440 if (!(device = create_device(d3d, window, window, TRUE)))
10442 skip("Failed to create a D3D device, skipping tests.\n");
10443 goto done;
10446 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10447 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
10448 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
10450 skip("No shader model 3 support, skipping tests.\n");
10451 IDirect3DDevice9_Release(device);
10452 goto done;
10455 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10456 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
10457 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
10458 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
10459 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
10460 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
10461 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
10462 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
10463 hr = IDirect3DDevice9_SetPixelShader(device, shader);
10464 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
10465 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
10466 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
10467 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10468 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
10469 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
10470 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
10472 hr = IDirect3DDevice9_BeginScene(device);
10473 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10474 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
10475 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
10476 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
10477 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10478 hr = IDirect3DDevice9_EndScene(device);
10479 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10481 /* This has to be pixel exact */
10482 color = getPixelColor(device, 319, 239);
10483 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
10484 color = getPixelColor(device, 320, 239);
10485 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
10486 color = getPixelColor(device, 319, 240);
10487 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
10488 color = getPixelColor(device, 320, 240);
10489 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
10490 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10492 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
10493 &surface, NULL);
10494 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
10495 hr = IDirect3DDevice9_BeginScene(device);
10496 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10497 constant[2] = 16; constant[3] = 16;
10498 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
10499 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
10500 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
10501 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10502 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
10503 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10504 hr = IDirect3DDevice9_EndScene(device);
10505 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10507 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
10508 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
10510 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
10511 color = *pos & 0x00ffffff;
10512 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
10513 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
10514 color = *pos & 0x00ffffff;
10515 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
10516 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
10517 color = *pos & 0x00ffffff;
10518 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
10519 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
10520 color = *pos & 0x00ffffff;
10521 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
10523 hr = IDirect3DSurface9_UnlockRect(surface);
10524 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
10526 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
10527 * have full control over the multisampling setting inside this test
10529 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
10530 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
10531 hr = IDirect3DDevice9_BeginScene(device);
10532 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10533 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
10534 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
10535 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
10536 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10537 hr = IDirect3DDevice9_EndScene(device);
10538 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10540 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10541 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
10543 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
10544 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
10546 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
10547 color = *pos & 0x00ffffff;
10548 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
10550 hr = IDirect3DSurface9_UnlockRect(surface);
10551 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
10553 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
10554 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
10555 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10556 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
10557 IDirect3DPixelShader9_Release(shader);
10558 IDirect3DPixelShader9_Release(shader_frac);
10559 IDirect3DVertexShader9_Release(vshader);
10560 if(surface) IDirect3DSurface9_Release(surface);
10561 IDirect3DSurface9_Release(backbuffer);
10562 refcount = IDirect3DDevice9_Release(device);
10563 ok(!refcount, "Device has %u references left.\n", refcount);
10564 done:
10565 IDirect3D9_Release(d3d);
10566 DestroyWindow(window);
10569 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
10571 D3DCOLOR color;
10573 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
10574 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
10575 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
10576 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
10577 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
10579 ++r;
10580 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
10581 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
10582 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
10583 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
10584 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
10586 return TRUE;
10589 static void test_pointsize(void)
10591 static const float a = 1.0f, b = 1.0f, c = 1.0f;
10592 float ptsize, ptsizemax_orig, ptsizemin_orig;
10593 IDirect3DSurface9 *rt, *backbuffer;
10594 IDirect3DTexture9 *tex1, *tex2;
10595 IDirect3DDevice9 *device;
10596 IDirect3DVertexShader9 *vs;
10597 IDirect3DPixelShader9 *ps;
10598 D3DLOCKED_RECT lr;
10599 IDirect3D9 *d3d;
10600 D3DCOLOR color;
10601 ULONG refcount;
10602 D3DCAPS9 caps;
10603 HWND window;
10604 HRESULT hr;
10605 unsigned int i, j;
10607 static const RECT rect = {0, 0, 128, 128};
10608 static const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000, 0x00000000, 0x00000000};
10609 static const DWORD tex2_data[4] = {0x00000000, 0x0000ff00, 0x00000000, 0x0000ff00};
10610 static const float vertices[] =
10612 64.0f, 64.0f, 0.1f,
10613 128.0f, 64.0f, 0.1f,
10614 192.0f, 64.0f, 0.1f,
10615 256.0f, 64.0f, 0.1f,
10616 320.0f, 64.0f, 0.1f,
10617 384.0f, 64.0f, 0.1f,
10618 448.0f, 64.0f, 0.1f,
10619 512.0f, 64.0f, 0.1f,
10621 static const struct
10623 float x, y, z;
10624 float point_size;
10626 vertex_pointsize = {64.0f, 64.0f, 0.1f, 48.0f},
10627 vertex_pointsize_scaled = {64.0f, 64.0f, 0.1f, 24.0f},
10628 vertex_pointsize_zero = {64.0f, 64.0f, 0.1f, 0.0f};
10629 /* Writing a texture coordinate from the shader is technically unnecessary, but is required
10630 * to make Windows AMD r500 drivers work. Without it, texture coordinates in the pixel
10631 * shaders are 0. */
10632 static const DWORD vshader_code[] =
10634 0xfffe0101, /* vs_1_1 */
10635 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10636 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10637 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10638 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10639 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
10640 0x00000001, 0xe00f0000, 0x90e40000, /* mov oT0, v0 */
10641 0x00000001, 0xe00f0001, 0x90e40000, /* mov oT1, v0 */
10642 0x0000ffff
10644 static const DWORD vshader_psize_code[] =
10646 0xfffe0101, /* vs_1_1 */
10647 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10648 0x0000001f, 0x80000004, 0x900f0001, /* dcl_psize v1 */
10649 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10650 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10651 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10652 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
10653 0x00000001, 0xc00f0002, 0x90000001, /* mov oPts, v1.x */
10654 0x00000001, 0xe00f0000, 0x90e40000, /* mov oT0, v0 */
10655 0x00000001, 0xe00f0001, 0x90e40000, /* mov oT1, v0 */
10656 0x0000ffff
10658 static const DWORD pshader_code[] =
10660 0xffff0101, /* ps_1_1 */
10661 0x00000042, 0xb00f0000, /* tex t0 */
10662 0x00000042, 0xb00f0001, /* tex t1 */
10663 0x00000002, 0x800f0000, 0xb0e40000, 0xb0e40001, /* add r0, t0, t1 */
10664 0x0000ffff
10666 static const DWORD pshader2_code[] =
10668 0xffff0200, /* ps_2_0 */
10669 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
10670 0x0200001f, 0x80000000, 0xb00f0001, /* dcl t1 */
10671 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10672 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10673 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
10674 0x03000042, 0x800f0001, 0xb0e40001, 0xa0e40801, /* texld r1, t1, s1 */
10675 0x03000002, 0x800f0000, 0x80e40000, 0x80e40001, /* add r0, r0, r1 */
10676 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
10677 0x0000ffff
10679 static const DWORD pshader2_zw_code[] =
10681 0xffff0200, /* ps_2_0 */
10682 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
10683 0x0200001f, 0x80000000, 0xb00f0001, /* dcl t1 */
10684 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10685 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10686 0x02000001, 0x80030000, 0xb01b0000, /* mov r0.xy, t0.wzyx */
10687 0x02000001, 0x80030001, 0xb01b0001, /* mov r1.xy, t1.wzyx */
10688 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, /* texld r0, r0, s0 */
10689 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40801, /* texld r1, r1, s1 */
10690 0x03000002, 0x800f0000, 0x80e40000, 0x80e40001, /* add r0, r0, r1 */
10691 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
10692 0x0000ffff
10694 static const DWORD vshader3_code[] =
10696 0xfffe0300, /* vs_3_0 */
10697 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10698 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
10699 0x0200001f, 0x80000005, 0xe00f0001, /* dcl_texcoord0 o1 */
10700 0x0200001f, 0x80010005, 0xe00f0002, /* dcl_texcoord1 o2 */
10701 0x03000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10702 0x04000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10703 0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10704 0x04000004, 0xe00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad o0, v0.w, c3, r0 */
10705 0x02000001, 0xe00f0001, 0x90000000, /* mov o1, v0.x */
10706 0x02000001, 0xe00f0002, 0x90000000, /* mov o2, v0.x */
10707 0x0000ffff
10709 static const DWORD vshader3_psize_code[] =
10711 0xfffe0300, /* vs_3_0 */
10712 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10713 0x0200001f, 0x80000004, 0x90010001, /* dcl_psize v1.x */
10714 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
10715 0x0200001f, 0x80000004, 0xe00f0001, /* dcl_psize o1 */
10716 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
10717 0x0200001f, 0x80010005, 0xe00f0003, /* dcl_texcoord1 o3 */
10718 0x03000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10719 0x04000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10720 0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10721 0x04000004, 0xe00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad o0, v0.w, c3, r0 */
10722 0x02000001, 0xe00f0001, 0x90000001, /* mov o1, v1.x */
10723 0x02000001, 0xe00f0002, 0x90000000, /* mov o2, v0.x */
10724 0x02000001, 0xe00f0003, 0x90000000, /* mov o3, v0.x */
10725 0x0000ffff
10727 static const DWORD pshader3_code[] =
10729 0xffff0300, /* ps_3_0 */
10730 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
10731 0x0200001f, 0x80010005, 0x900f0001, /* dcl_texcoord1 v1 */
10732 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10733 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10734 0x03000042, 0x800f0000, 0x90e40000, 0xa0e40800, /* texld r0, v0, s0 */
10735 0x03000042, 0x800f0001, 0x90e40001, 0xa0e40801, /* texld r1, v1, s1 */
10736 0x03000002, 0x800f0800, 0x80e40000, 0x80e40001, /* add oC0, r0, r1 */
10737 0x0000ffff
10739 static const DWORD pshader3_zw_code[] =
10741 0xffff0300, /* ps_3_0 */
10742 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
10743 0x0200001f, 0x80010005, 0x900f0001, /* dcl_texcoord1 v1 */
10744 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10745 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10746 0x03000042, 0x800f0000, 0x90fe0000, 0xa0e40800, /* texld r0, v0.zw, s0 */
10747 0x03000042, 0x800f0001, 0x90fe0001, 0xa0e40801, /* texld r1, v1.zw, s1 */
10748 0x03000002, 0x800f0800, 0x80e40000, 0x80e40001, /* add oC0, r0, r1 */
10749 0x0000ffff
10751 static const struct test_shader
10753 DWORD version;
10754 const DWORD *code;
10756 novs = {0, NULL},
10757 vs1 = {D3DVS_VERSION(1, 1), vshader_code},
10758 vs1_psize = {D3DVS_VERSION(1, 1), vshader_psize_code},
10759 vs3 = {D3DVS_VERSION(3, 0), vshader3_code},
10760 vs3_psize = {D3DVS_VERSION(3, 0), vshader3_psize_code},
10761 nops = {0, NULL},
10762 ps1 = {D3DPS_VERSION(1, 1), pshader_code},
10763 ps2 = {D3DPS_VERSION(2, 0), pshader2_code},
10764 ps2_zw = {D3DPS_VERSION(2, 0), pshader2_zw_code},
10765 ps3 = {D3DPS_VERSION(3, 0), pshader3_code},
10766 ps3_zw = {D3DPS_VERSION(3, 0), pshader3_zw_code};
10767 static const struct
10769 const struct test_shader *vs;
10770 const struct test_shader *ps;
10771 DWORD accepted_fvf;
10772 unsigned int nonscaled_size, scaled_size;
10773 BOOL gives_0_0_texcoord;
10774 BOOL allow_broken;
10776 test_setups[] =
10778 {&novs, &nops, D3DFVF_XYZ, 32, 45, FALSE, FALSE},
10779 {&vs1, &ps1, D3DFVF_XYZ, 32, 32, FALSE, FALSE},
10780 {&novs, &ps1, D3DFVF_XYZ, 32, 45, FALSE, FALSE},
10781 {&vs1, &nops, D3DFVF_XYZ, 32, 32, FALSE, FALSE},
10782 {&novs, &ps2, D3DFVF_XYZ, 32, 45, FALSE, TRUE},
10783 {&novs, &ps2_zw, D3DFVF_XYZ, 32, 45, TRUE, FALSE},
10784 {&vs1, &ps2, D3DFVF_XYZ, 32, 32, FALSE, TRUE},
10785 {&vs1, &ps2_zw, D3DFVF_XYZ, 32, 32, TRUE, FALSE},
10786 {&vs3, &ps3, D3DFVF_XYZ, 32, 32, FALSE, TRUE},
10787 {&vs3, &ps3_zw, D3DFVF_XYZ, 32, 32, TRUE, FALSE},
10788 {&novs, &nops, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 33, FALSE, FALSE},
10789 {&vs1_psize, &ps1, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 24, FALSE, FALSE},
10790 {&vs3_psize, &ps3, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 24, FALSE, TRUE},
10792 static const struct
10794 BOOL zero_size;
10795 BOOL scale;
10796 BOOL override_min;
10797 DWORD fvf;
10798 const void *vertex_data;
10799 unsigned int vertex_size;
10801 tests[] =
10803 {FALSE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10804 {FALSE, TRUE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10805 {FALSE, FALSE, TRUE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10806 {TRUE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10807 {FALSE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
10808 {FALSE, TRUE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_scaled, sizeof(vertex_pointsize_scaled)},
10809 {FALSE, FALSE, TRUE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
10810 {TRUE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_zero, sizeof(vertex_pointsize_zero)},
10812 /* Transforms the coordinate system [-1.0;1.0]x[1.0;-1.0] to
10813 * [0.0;0.0]x[640.0;480.0]. Z is untouched. */
10814 D3DMATRIX matrix =
10816 2.0f / 640.0f, 0.0f, 0.0f, 0.0f,
10817 0.0f, -2.0f / 480.0f, 0.0f, 0.0f,
10818 0.0f, 0.0f, 1.0f, 0.0f,
10819 -1.0f, 1.0f, 0.0f, 1.0f,
10820 }}};
10822 window = create_window();
10823 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10824 ok(!!d3d, "Failed to create a D3D object.\n");
10825 if (!(device = create_device(d3d, window, window, TRUE)))
10827 skip("Failed to create a D3D device, skipping tests.\n");
10828 goto done;
10831 memset(&caps, 0, sizeof(caps));
10832 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10833 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
10834 if(caps.MaxPointSize < 32.0) {
10835 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
10836 IDirect3DDevice9_Release(device);
10837 goto done;
10840 /* The r500 Windows driver needs a draw with regular texture coordinates at least once during the
10841 * device's lifetime, otherwise texture coordinate generation only works for texture 0. */
10842 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
10843 ok(SUCCEEDED(hr), "Failed to set FVF, hr=%#x.\n", hr);
10844 hr = IDirect3DDevice9_BeginScene(device);
10845 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10846 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, vertices, sizeof(float) * 5);
10847 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10848 hr = IDirect3DDevice9_EndScene(device);
10849 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10851 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10852 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
10853 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10854 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
10855 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
10856 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
10857 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10858 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
10860 hr = IDirect3DDevice9_BeginScene(device);
10861 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10863 ptsize = 15.0f;
10864 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10865 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10866 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
10867 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10869 ptsize = 31.0f;
10870 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10871 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10872 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
10873 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10875 ptsize = 30.75f;
10876 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10877 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10878 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
10879 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10881 if (caps.MaxPointSize >= 63.0f)
10883 ptsize = 63.0f;
10884 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10885 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10886 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
10887 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10889 ptsize = 62.75f;
10890 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10891 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10892 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
10893 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10896 ptsize = 1.0f;
10897 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10898 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10899 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
10900 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10902 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *)&ptsizemax_orig);
10903 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
10904 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *)&ptsizemin_orig);
10905 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
10907 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
10908 ptsize = 15.0f;
10909 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10910 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10911 ptsize = 1.0f;
10912 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsize);
10913 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10914 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
10915 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10917 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsizemax_orig);
10918 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10920 /* pointsize < pointsize_min < pointsize_max?
10921 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
10922 ptsize = 1.0f;
10923 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10924 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10925 ptsize = 15.0f;
10926 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
10927 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10928 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
10929 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10931 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsizemin_orig);
10932 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10934 hr = IDirect3DDevice9_EndScene(device);
10935 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10937 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
10938 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
10939 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
10941 if (caps.MaxPointSize >= 63.0)
10943 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
10944 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
10947 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
10948 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
10949 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
10950 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
10951 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
10953 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10955 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
10956 * generates texture coordinates for the point(result: Yes, it does)
10958 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
10959 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
10960 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
10962 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10963 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
10965 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
10966 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
10967 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
10968 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
10969 memset(&lr, 0, sizeof(lr));
10970 hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
10971 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
10972 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
10973 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
10974 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
10975 memset(&lr, 0, sizeof(lr));
10976 hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
10977 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
10978 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
10979 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
10980 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
10981 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
10982 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
10983 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
10984 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
10985 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10986 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10987 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10988 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10989 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
10990 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10991 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10992 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10993 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
10994 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10996 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
10997 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
10998 ptsize = 32.0;
10999 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
11000 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
11002 hr = IDirect3DDevice9_BeginScene(device);
11003 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11004 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
11005 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11006 hr = IDirect3DDevice9_EndScene(device);
11007 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11009 color = getPixelColor(device, 64-4, 64-4);
11010 ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
11011 color = getPixelColor(device, 64-4, 64+4);
11012 ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
11013 color = getPixelColor(device, 64+4, 64+4);
11014 ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
11015 color = getPixelColor(device, 64+4, 64-4);
11016 ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
11017 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11019 U(matrix).m[0][0] = 1.0f / 64.0f;
11020 U(matrix).m[1][1] = -1.0f / 64.0f;
11021 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
11022 ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
11024 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11025 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11027 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
11028 D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
11029 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11031 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_A, *(DWORD *)&a);
11032 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
11033 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_B, *(DWORD *)&b);
11034 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
11035 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_C, *(DWORD *)&c);
11036 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
11037 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
11039 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, &S(U(matrix))._11, 4);
11040 ok(SUCCEEDED(hr), "Failed to set vertex shader constants, hr %#x.\n", hr);
11043 if (caps.MaxPointSize < 63.0f)
11045 skip("MaxPointSize %f < 63.0, skipping some tests.\n", caps.MaxPointSize);
11046 goto cleanup;
11049 for (i = 0; i < sizeof(test_setups) / sizeof(test_setups[0]); ++i)
11051 if (caps.VertexShaderVersion < test_setups[i].vs->version
11052 || caps.PixelShaderVersion < test_setups[i].ps->version)
11054 skip("Vertex / pixel shader version not supported, skipping test.\n");
11055 continue;
11057 if (test_setups[i].vs->code)
11059 hr = IDirect3DDevice9_CreateVertexShader(device, test_setups[i].vs->code, &vs);
11060 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
11062 else
11064 vs = NULL;
11066 if (test_setups[i].ps->code)
11068 hr = IDirect3DDevice9_CreatePixelShader(device, test_setups[i].ps->code, &ps);
11069 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
11071 else
11073 ps = NULL;
11076 hr = IDirect3DDevice9_SetVertexShader(device, vs);
11077 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
11078 hr = IDirect3DDevice9_SetPixelShader(device, ps);
11079 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
11081 for (j = 0; j < sizeof(tests) / sizeof(tests[0]); ++j)
11083 BOOL allow_broken = test_setups[i].allow_broken;
11084 unsigned int size = tests[j].override_min ? 63 : tests[j].zero_size ? 0 : tests[j].scale
11085 ? test_setups[i].scaled_size : test_setups[i].nonscaled_size;
11087 if (test_setups[i].accepted_fvf != tests[j].fvf)
11088 continue;
11090 ptsize = tests[j].zero_size ? 0.0f : 32.0f;
11091 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
11092 ok(SUCCEEDED(hr), "Failed to set pointsize, hr %#x.\n", hr);
11094 ptsize = tests[j].override_min ? 63.0f : tests[j].zero_size ? 0.0f : ptsizemin_orig;
11095 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
11096 ok(SUCCEEDED(hr), "Failed to set minimum pointsize, hr %#x.\n", hr);
11098 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALEENABLE, tests[j].scale);
11099 ok(SUCCEEDED(hr), "Failed setting point scale state, hr %#x.\n", hr);
11101 hr = IDirect3DDevice9_SetFVF(device, tests[j].fvf);
11102 ok(SUCCEEDED(hr), "Failed setting FVF, hr %#x.\n", hr);
11104 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11105 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11106 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
11107 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
11109 hr = IDirect3DDevice9_BeginScene(device);
11110 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11111 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1,
11112 tests[j].vertex_data, tests[j].vertex_size);
11113 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11114 hr = IDirect3DDevice9_EndScene(device);
11115 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11117 hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
11118 ok(SUCCEEDED(hr), "Failed to blit, hr %#x.\n", hr);
11119 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11120 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11122 if (tests[j].zero_size)
11124 /* Technically 0 pointsize is undefined in OpenGL but in practice it seems like
11125 * it does the "useful" thing on all the drivers I tried. */
11126 /* On WARP it does draw some pixels, most of the time. */
11127 color = getPixelColor(device, 64, 64);
11128 ok(color_match(color, 0x0000ffff, 0)
11129 || broken(color_match(color, 0x00ff0000, 0))
11130 || broken(color_match(color, 0x00ffff00, 0))
11131 || broken(color_match(color, 0x00000000, 0))
11132 || broken(color_match(color, 0x0000ff00, 0)),
11133 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
11135 else
11137 struct surface_readback rb;
11139 get_rt_readback(backbuffer, &rb);
11140 /* On AMD apparently only the first texcoord is modified by the point coordinates
11141 * when using SM2/3 pixel shaders. */
11142 color = get_readback_color(&rb, 64 - size / 2 + 1, 64 - size / 2 + 1);
11143 ok(color_match(color, 0x00ff0000, 0),
11144 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
11145 color = get_readback_color(&rb, 64 + size / 2 - 1, 64 - size / 2 + 1);
11146 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x00ffff00, 0)
11147 || (allow_broken && broken(color_match(color, 0x00ff0000, 0))),
11148 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
11149 color = get_readback_color(&rb, 64 - size / 2 + 1, 64 + size / 2 - 1);
11150 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x00000000, 0),
11151 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
11152 color = get_readback_color(&rb, 64 + size / 2 - 1, 64 + size / 2 - 1);
11153 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x0000ff00, 0)
11154 || (allow_broken && broken(color_match(color, 0x00000000, 0))),
11155 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
11157 color = get_readback_color(&rb, 64 - size / 2 - 1, 64 - size / 2 - 1);
11158 ok(color_match(color, 0xff00ffff, 0),
11159 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
11160 color = get_readback_color(&rb, 64 + size / 2 + 1, 64 - size / 2 - 1);
11161 ok(color_match(color, 0xff00ffff, 0),
11162 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
11163 color = get_readback_color(&rb, 64 - size / 2 - 1, 64 + size / 2 + 1);
11164 ok(color_match(color, 0xff00ffff, 0),
11165 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
11166 color = get_readback_color(&rb, 64 + size / 2 + 1, 64 + size / 2 + 1);
11167 ok(color_match(color, 0xff00ffff, 0),
11168 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
11170 release_surface_readback(&rb);
11173 IDirect3DDevice9_SetVertexShader(device, NULL);
11174 IDirect3DDevice9_SetPixelShader(device, NULL);
11175 if (vs)
11176 IDirect3DVertexShader9_Release(vs);
11177 if (ps)
11178 IDirect3DVertexShader9_Release(ps);
11181 cleanup:
11182 IDirect3DSurface9_Release(backbuffer);
11183 IDirect3DSurface9_Release(rt);
11185 IDirect3DTexture9_Release(tex1);
11186 IDirect3DTexture9_Release(tex2);
11187 refcount = IDirect3DDevice9_Release(device);
11188 ok(!refcount, "Device has %u references left.\n", refcount);
11189 done:
11190 IDirect3D9_Release(d3d);
11191 DestroyWindow(window);
11194 static void multiple_rendertargets_test(void)
11196 IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
11197 IDirect3DPixelShader9 *ps1, *ps2;
11198 IDirect3DTexture9 *tex1, *tex2;
11199 IDirect3DVertexShader9 *vs;
11200 IDirect3DDevice9 *device;
11201 IDirect3D9 *d3d;
11202 ULONG refcount;
11203 D3DCAPS9 caps;
11204 DWORD color;
11205 HWND window;
11206 HRESULT hr;
11207 UINT i, j;
11209 static const DWORD vshader_code[] =
11211 0xfffe0300, /* vs_3_0 */
11212 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11213 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
11214 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
11215 0x0000ffff /* end */
11217 static const DWORD pshader_code1[] =
11219 0xffff0300, /* ps_3_0 */
11220 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
11221 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
11222 0x0000ffff /* end */
11224 static const DWORD pshader_code2[] =
11226 0xffff0300, /* ps_3_0 */
11227 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
11228 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
11229 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
11230 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
11231 0x0000ffff /* end */
11233 static const float quad[] =
11235 -1.0f, -1.0f, 0.1f,
11236 -1.0f, 1.0f, 0.1f,
11237 1.0f, -1.0f, 0.1f,
11238 1.0f, 1.0f, 0.1f,
11240 static const float texquad[] =
11242 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
11243 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
11244 0.0f, -1.0f, 0.1f, 1.0f, 0.0f,
11245 0.0f, 1.0f, 0.1f, 1.0f, 1.0f,
11247 0.0f, -1.0f, 0.1f, 0.0f, 0.0f,
11248 0.0f, 1.0f, 0.1f, 0.0f, 1.0f,
11249 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
11250 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
11253 window = create_window();
11254 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11255 ok(!!d3d, "Failed to create a D3D object.\n");
11256 if (!(device = create_device(d3d, window, window, TRUE)))
11258 skip("Failed to create a D3D device, skipping tests.\n");
11259 goto done;
11262 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11263 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
11264 if (caps.NumSimultaneousRTs < 2)
11266 skip("Only 1 simultaneous render target supported, skipping MRT test.\n");
11267 IDirect3DDevice9_Release(device);
11268 goto done;
11270 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
11272 skip("No shader model 3 support, skipping tests.\n");
11273 IDirect3DDevice9_Release(device);
11274 goto done;
11277 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
11278 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
11280 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
11281 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
11282 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
11284 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
11285 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
11286 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
11287 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
11288 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
11289 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
11290 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
11291 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
11292 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code1, &ps1);
11293 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
11294 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code2, &ps2);
11295 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
11297 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
11298 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
11299 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
11300 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
11301 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
11302 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
11304 hr = IDirect3DDevice9_SetVertexShader(device, vs);
11305 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
11306 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
11307 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11308 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
11309 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11310 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
11311 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
11313 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
11314 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
11315 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
11316 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11317 color = getPixelColorFromSurface(readback, 8, 8);
11318 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
11319 "Expected color 0x000000ff, got 0x%08x.\n", color);
11320 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
11321 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11322 color = getPixelColorFromSurface(readback, 8, 8);
11323 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
11324 "Expected color 0x000000ff, got 0x%08x.\n", color);
11326 /* Render targets not written by the pixel shader should be unmodified. */
11327 hr = IDirect3DDevice9_SetPixelShader(device, ps1);
11328 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
11329 hr = IDirect3DDevice9_BeginScene(device);
11330 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11331 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
11332 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11333 hr = IDirect3DDevice9_EndScene(device);
11334 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11335 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
11336 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11337 color = getPixelColorFromSurface(readback, 8, 8);
11338 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
11339 "Expected color 0xff00ff00, got 0x%08x.\n", color);
11340 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
11341 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11342 for (i = 6; i < 10; ++i)
11344 for (j = 6; j < 10; ++j)
11346 color = getPixelColorFromSurface(readback, j, i);
11347 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
11348 "Expected color 0xff0000ff, got 0x%08x at %u, %u.\n", color, j, i);
11352 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
11353 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
11354 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
11355 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11356 color = getPixelColorFromSurface(readback, 8, 8);
11357 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
11358 "Expected color 0x0000ff00, got 0x%08x.\n", color);
11359 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
11360 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11361 color = getPixelColorFromSurface(readback, 8, 8);
11362 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
11363 "Expected color 0x0000ff00, got 0x%08x.\n", color);
11365 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
11366 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
11368 hr = IDirect3DDevice9_BeginScene(device);
11369 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11371 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
11372 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11374 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11375 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11376 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11377 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
11378 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11379 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
11380 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
11381 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11382 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
11383 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11384 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11385 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
11387 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
11388 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
11389 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
11390 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11392 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
11393 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
11394 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
11395 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11397 hr = IDirect3DDevice9_EndScene(device);
11398 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11400 color = getPixelColor(device, 160, 240);
11401 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
11402 color = getPixelColor(device, 480, 240);
11403 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
11404 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11406 IDirect3DPixelShader9_Release(ps2);
11407 IDirect3DPixelShader9_Release(ps1);
11408 IDirect3DVertexShader9_Release(vs);
11409 IDirect3DTexture9_Release(tex1);
11410 IDirect3DTexture9_Release(tex2);
11411 IDirect3DSurface9_Release(surf1);
11412 IDirect3DSurface9_Release(surf2);
11413 IDirect3DSurface9_Release(backbuf);
11414 IDirect3DSurface9_Release(readback);
11415 refcount = IDirect3DDevice9_Release(device);
11416 ok(!refcount, "Device has %u references left.\n", refcount);
11417 done:
11418 IDirect3D9_Release(d3d);
11419 DestroyWindow(window);
11422 static void pixelshader_blending_test(void)
11424 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
11425 IDirect3DTexture9 *offscreenTexture = NULL;
11426 IDirect3DDevice9 *device;
11427 IDirect3D9 *d3d;
11428 ULONG refcount;
11429 int fmt_index;
11430 DWORD color;
11431 HWND window;
11432 HRESULT hr;
11434 static const struct
11436 const char *fmtName;
11437 D3DFORMAT textureFormat;
11438 D3DCOLOR resultColorBlending;
11439 D3DCOLOR resultColorNoBlending;
11441 test_formats[] =
11443 {"D3DFMT_G16R16", D3DFMT_G16R16, 0x001820ff, 0x002010ff},
11444 {"D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff},
11445 {"D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001820ff, 0x002010ff},
11446 {"D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00182000, 0x00201000},
11447 {"D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff},
11448 {"D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001820ff, 0x002010ff},
11449 {"D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00182000, 0x00201000},
11450 {"D3DFMT_L8", D3DFMT_L8, 0x00181818, 0x00202020},
11452 static const float quad[][5] =
11454 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
11455 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
11456 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
11457 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
11459 static const struct
11461 struct vec3 position;
11462 DWORD diffuse;
11464 quad1[] =
11466 {{-1.0f, -1.0f, 0.1f}, 0x80103000},
11467 {{-1.0f, 1.0f, 0.1f}, 0x80103000},
11468 {{ 1.0f, -1.0f, 0.1f}, 0x80103000},
11469 {{ 1.0f, 1.0f, 0.1f}, 0x80103000},
11471 quad2[] =
11473 {{-1.0f, -1.0f, 0.1f}, 0x80201000},
11474 {{-1.0f, 1.0f, 0.1f}, 0x80201000},
11475 {{ 1.0f, -1.0f, 0.1f}, 0x80201000},
11476 {{ 1.0f, 1.0f, 0.1f}, 0x80201000},
11479 window = create_window();
11480 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11481 ok(!!d3d, "Failed to create a D3D object.\n");
11482 if (!(device = create_device(d3d, window, window, TRUE)))
11484 skip("Failed to create a D3D device, skipping tests.\n");
11485 goto done;
11488 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
11489 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
11491 for (fmt_index = 0; fmt_index < sizeof(test_formats) / sizeof(*test_formats); ++fmt_index)
11493 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
11495 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11496 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
11498 skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
11499 continue;
11502 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
11503 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
11505 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
11506 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
11507 if(!offscreenTexture) {
11508 continue;
11511 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
11512 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
11513 if(!offscreen) {
11514 continue;
11517 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11518 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
11520 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11521 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11522 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
11523 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11524 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11525 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
11526 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11527 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
11528 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11529 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
11531 /* Below we will draw two quads with different colors and try to blend
11532 * them together. The result color is compared with the expected
11533 * outcome. */
11534 hr = IDirect3DDevice9_BeginScene(device);
11535 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11537 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
11538 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11539 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 1.0f, 0);
11540 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
11542 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
11543 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11545 /* Draw a quad using color 0x0010200. */
11546 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
11547 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11548 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
11549 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11550 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
11551 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11553 /* Draw a quad using color 0x0020100. */
11554 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
11555 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11556 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
11557 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11558 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
11559 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11561 /* We don't want to blend the result on the backbuffer. */
11562 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
11563 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11565 /* Prepare rendering the 'blended' texture quad to the backbuffer. */
11566 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11567 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11568 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)offscreenTexture);
11569 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
11571 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11572 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
11574 /* This time with the texture. */
11575 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
11576 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11578 hr = IDirect3DDevice9_EndScene(device);
11579 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11581 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11582 D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK)
11584 /* Compare the color of the center quad with our expectation. */
11585 color = getPixelColor(device, 320, 240);
11586 ok(color_match(color, test_formats[fmt_index].resultColorBlending, 1),
11587 "Offscreen failed for %s: Got color 0x%08x, expected 0x%08x.\n",
11588 test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
11590 else
11592 /* No pixel shader blending is supported so expect garbage. The
11593 * type of 'garbage' depends on the driver version and OS. E.g. on
11594 * G16R16 ATI reports (on old r9600 drivers) 0x00ffffff and on
11595 * modern ones 0x002010ff which is also what NVIDIA reports. On
11596 * Vista NVIDIA seems to report 0x00ffffff on Geforce7 cards. */
11597 color = getPixelColor(device, 320, 240);
11598 ok((color == 0x00ffffff) || (color == test_formats[fmt_index].resultColorNoBlending),
11599 "Offscreen failed for %s: Got unexpected color 0x%08x, expected no color blending.\n",
11600 test_formats[fmt_index].fmtName, color);
11602 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11604 IDirect3DDevice9_SetTexture(device, 0, NULL);
11605 if(offscreenTexture) {
11606 IDirect3DTexture9_Release(offscreenTexture);
11608 if(offscreen) {
11609 IDirect3DSurface9_Release(offscreen);
11613 IDirect3DSurface9_Release(backbuffer);
11614 refcount = IDirect3DDevice9_Release(device);
11615 ok(!refcount, "Device has %u references left.\n", refcount);
11616 done:
11617 IDirect3D9_Release(d3d);
11618 DestroyWindow(window);
11621 static void tssargtemp_test(void)
11623 IDirect3DDevice9 *device;
11624 IDirect3D9 *d3d;
11625 D3DCOLOR color;
11626 ULONG refcount;
11627 D3DCAPS9 caps;
11628 HWND window;
11629 HRESULT hr;
11631 static const struct
11633 struct vec3 position;
11634 DWORD diffuse;
11636 quad[] =
11638 {{-1.0f, -1.0f, 0.1f}, 0x00ff0000},
11639 {{-1.0f, 1.0f, 0.1f}, 0x00ff0000},
11640 {{ 1.0f, -1.0f, 0.1f}, 0x00ff0000},
11641 {{ 1.0f, 1.0f, 0.1f}, 0x00ff0000},
11644 window = create_window();
11645 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11646 ok(!!d3d, "Failed to create a D3D object.\n");
11647 if (!(device = create_device(d3d, window, window, TRUE)))
11649 skip("Failed to create a D3D device, skipping tests.\n");
11650 goto done;
11653 memset(&caps, 0, sizeof(caps));
11654 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11655 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
11656 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
11657 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
11658 IDirect3DDevice9_Release(device);
11659 goto done;
11662 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
11663 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11665 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11666 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11667 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
11668 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11670 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11671 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11672 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
11673 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11674 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
11675 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11677 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
11678 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11679 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
11680 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11681 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
11682 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11684 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
11685 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11687 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
11688 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
11689 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11690 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
11691 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11692 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
11694 hr = IDirect3DDevice9_BeginScene(device);
11695 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11696 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
11697 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11698 hr = IDirect3DDevice9_EndScene(device);
11699 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11701 color = getPixelColor(device, 320, 240);
11702 ok(color == 0x00ffff00, "TSSARGTEMP test returned color 0x%08x, expected 0x00ffff00\n", color);
11703 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11705 refcount = IDirect3DDevice9_Release(device);
11706 ok(!refcount, "Device has %u references left.\n", refcount);
11707 done:
11708 IDirect3D9_Release(d3d);
11709 DestroyWindow(window);
11712 /* Drawing Indexed Geometry with instances*/
11713 static void stream_test(void)
11715 IDirect3DVertexDeclaration9 *pDecl = NULL;
11716 IDirect3DVertexShader9 *shader = NULL;
11717 IDirect3DVertexBuffer9 *vb3 = NULL;
11718 IDirect3DVertexBuffer9 *vb2 = NULL;
11719 IDirect3DVertexBuffer9 *vb = NULL;
11720 IDirect3DIndexBuffer9 *ib = NULL;
11721 IDirect3DDevice9 *device;
11722 IDirect3D9 *d3d;
11723 ULONG refcount;
11724 D3DCAPS9 caps;
11725 DWORD color;
11726 HWND window;
11727 unsigned i;
11728 HRESULT hr;
11729 BYTE *data;
11730 DWORD ind;
11732 static const struct testdata
11734 DWORD idxVertex; /* number of instances in the first stream */
11735 DWORD idxColor; /* number of instances in the second stream */
11736 DWORD idxInstance; /* should be 1 ?? */
11737 DWORD color1; /* color 1 instance */
11738 DWORD color2; /* color 2 instance */
11739 DWORD color3; /* color 3 instance */
11740 DWORD color4; /* color 4 instance */
11741 WORD strVertex; /* specify which stream to use 0-2*/
11742 WORD strColor;
11743 WORD strInstance;
11744 DWORD explicit_zero_freq;
11746 testcases[]=
11748 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
11749 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
11750 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
11751 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
11752 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 4 */
11753 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
11754 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
11755 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
11756 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 8 */
11757 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 9 */
11758 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 10 */
11759 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 11 */
11761 /* The number of instances is read from stream zero, even if stream zero is not
11762 * in use. Exact behavior of this corner case depends on the presence or absence
11763 * of D3DSTREAMSOURCE_INDEXEDDATA. r500 GPUs need D3DSTREAMSOURCE_INDEXEDDATA
11764 * to be present, otherwise they disable instancing and behave like in a non-
11765 * instanced draw. Nvidia drivers do not show different behavior with or without
11766 * D3DSTREAMSOURCE_INDEXEDDATA. Note however that setting the value to 0 is not
11767 * allowed by the d3d runtime.
11769 * The meaning of (D3DSTREAMSOURCE_INDEXEDDATA | 0) is driver dependent. r500
11770 * will fall back to non-instanced drawing. Geforce 7 will draw 1 instance.
11771 * Geforce 8+ will draw nothing. */
11772 {3, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1, 1}, /* 12 */
11773 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 2, 3, 1, 2}, /* 13 */
11774 {1, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 2, 3, 1, 3}, /* 14 */
11775 {0, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 3, 1, 4}, /* 15 */
11777 static const DWORD shader_code[] =
11779 0xfffe0101, /* vs_1_1 */
11780 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11781 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
11782 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
11783 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
11784 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
11785 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
11786 0x0000ffff
11788 /* Note that this set of coordinates and instancepos[] have an implicit
11789 * w = 1.0, which is added to w = 2.0, so the perspective divide divides
11790 * x, y and z by 2. */
11791 static const float quad[][3] =
11793 {-0.5f, -0.5f, 1.1f}, /*0 */
11794 {-0.5f, 0.5f, 1.1f}, /*1 */
11795 { 0.5f, -0.5f, 1.1f}, /*2 */
11796 { 0.5f, 0.5f, 1.1f}, /*3 */
11798 static const float vertcolor[][4] =
11800 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
11801 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
11802 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
11803 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
11805 /* 4 position for 4 instances */
11806 static const float instancepos[][3] =
11808 {-0.6f,-0.6f, 0.0f},
11809 { 0.6f,-0.6f, 0.0f},
11810 { 0.6f, 0.6f, 0.0f},
11811 {-0.6f, 0.6f, 0.0f},
11813 static const short indices[] = {0, 1, 2, 2, 1, 3};
11814 D3DVERTEXELEMENT9 decl[] =
11816 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
11817 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
11818 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
11819 D3DDECL_END()
11822 window = create_window();
11823 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11824 ok(!!d3d, "Failed to create a D3D object.\n");
11825 if (!(device = create_device(d3d, window, window, TRUE)))
11827 skip("Failed to create a D3D device, skipping tests.\n");
11828 goto done;
11831 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11832 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
11833 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
11835 skip("No vs_3_0 support, skipping tests.\n");
11836 IDirect3DDevice9_Release(device);
11837 goto done;
11840 /* set the default value because it isn't done in wine? */
11841 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
11842 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11844 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
11845 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
11846 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11848 /* check wrong cases */
11849 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
11850 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11851 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11852 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11853 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
11854 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11855 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11856 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11857 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
11858 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11859 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11860 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11861 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
11862 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11863 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11864 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11865 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
11866 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11867 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11868 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11870 /* set the default value back */
11871 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
11872 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11874 /* create all VertexBuffers*/
11875 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
11876 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
11877 if(!vb) {
11878 skip("Failed to create a vertex buffer\n");
11879 IDirect3DDevice9_Release(device);
11880 goto done;
11882 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
11883 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
11884 if(!vb2) {
11885 skip("Failed to create a vertex buffer\n");
11886 goto out;
11888 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
11889 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
11890 if(!vb3) {
11891 skip("Failed to create a vertex buffer\n");
11892 goto out;
11895 /* create IndexBuffer*/
11896 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
11897 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
11898 if(!ib) {
11899 skip("Failed to create an index buffer\n");
11900 goto out;
11903 /* copy all Buffers (Vertex + Index)*/
11904 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
11905 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
11906 memcpy(data, quad, sizeof(quad));
11907 hr = IDirect3DVertexBuffer9_Unlock(vb);
11908 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
11909 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
11910 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
11911 memcpy(data, vertcolor, sizeof(vertcolor));
11912 hr = IDirect3DVertexBuffer9_Unlock(vb2);
11913 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
11914 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
11915 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
11916 memcpy(data, instancepos, sizeof(instancepos));
11917 hr = IDirect3DVertexBuffer9_Unlock(vb3);
11918 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
11919 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
11920 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
11921 memcpy(data, indices, sizeof(indices));
11922 hr = IDirect3DIndexBuffer9_Unlock(ib);
11923 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
11925 /* create VertexShader */
11926 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
11927 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
11928 if(!shader) {
11929 skip("Failed to create a vertex shader.\n");
11930 goto out;
11933 hr = IDirect3DDevice9_SetVertexShader(device, shader);
11934 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
11936 hr = IDirect3DDevice9_SetIndices(device, ib);
11937 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
11939 /* run all tests */
11940 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
11942 struct testdata act = testcases[i];
11943 decl[0].Stream = act.strVertex;
11944 decl[1].Stream = act.strColor;
11945 decl[2].Stream = act.strInstance;
11946 /* create VertexDeclarations */
11947 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
11948 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
11950 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
11951 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
11953 hr = IDirect3DDevice9_BeginScene(device);
11954 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11956 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
11957 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
11959 /* If stream 0 is unused, set the stream frequency regardless to show
11960 * that the number if instances is read from it. */
11961 if (act.strVertex && act.strColor && act.strInstance)
11963 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0,
11964 D3DSTREAMSOURCE_INDEXEDDATA | act.explicit_zero_freq);
11965 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11968 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex,
11969 (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
11970 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11971 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
11972 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11974 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor,
11975 (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
11976 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11977 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
11978 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11980 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance,
11981 (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
11982 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11983 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
11984 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11986 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
11987 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11988 hr = IDirect3DDevice9_EndScene(device);
11989 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11991 /* set all StreamSource && StreamSourceFreq back to default */
11992 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
11993 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11994 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
11995 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11996 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
11997 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11998 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
11999 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
12000 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
12001 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
12002 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
12003 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
12005 hr = IDirect3DVertexDeclaration9_Release(pDecl);
12006 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
12008 color = getPixelColor(device, 160, 360);
12009 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
12010 color = getPixelColor(device, 480, 360);
12011 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
12012 color = getPixelColor(device, 480, 120);
12013 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
12014 color = getPixelColor(device, 160, 120);
12015 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
12017 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12018 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
12021 out:
12022 if(vb) IDirect3DVertexBuffer9_Release(vb);
12023 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
12024 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
12025 if(ib)IDirect3DIndexBuffer9_Release(ib);
12026 if(shader)IDirect3DVertexShader9_Release(shader);
12027 refcount = IDirect3DDevice9_Release(device);
12028 ok(!refcount, "Device has %u references left.\n", refcount);
12029 done:
12030 IDirect3D9_Release(d3d);
12031 DestroyWindow(window);
12034 static void np2_stretch_rect_test(void)
12036 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
12037 IDirect3DTexture9 *dsttex = NULL;
12038 IDirect3DDevice9 *device;
12039 IDirect3D9 *d3d;
12040 D3DCOLOR color;
12041 ULONG refcount;
12042 HWND window;
12043 HRESULT hr;
12045 static const D3DRECT r1 = {0, 0, 50, 50 };
12046 static const D3DRECT r2 = {50, 0, 100, 50 };
12047 static const D3DRECT r3 = {50, 50, 100, 100};
12048 static const D3DRECT r4 = {0, 50, 50, 100};
12049 static const float quad[] =
12051 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
12052 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
12053 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
12054 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
12057 window = create_window();
12058 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12059 ok(!!d3d, "Failed to create a D3D object.\n");
12060 if (!(device = create_device(d3d, window, window, TRUE)))
12062 skip("Failed to create a D3D device, skipping tests.\n");
12063 goto done;
12066 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
12067 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
12069 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
12070 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
12071 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
12072 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
12074 if(!src || !dsttex) {
12075 skip("One or more test resources could not be created\n");
12076 goto cleanup;
12079 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
12080 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
12082 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
12083 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
12085 /* Clear the StretchRect destination for debugging */
12086 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
12087 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
12088 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
12089 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
12091 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
12092 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
12094 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
12095 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
12096 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
12097 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
12098 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
12099 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
12100 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
12101 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
12103 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
12104 * the target -> texture GL blit path
12106 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
12107 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
12108 IDirect3DSurface9_Release(dst);
12110 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
12111 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
12113 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
12114 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
12115 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
12116 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
12117 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12118 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
12119 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12120 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
12122 hr = IDirect3DDevice9_BeginScene(device);
12123 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12124 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
12125 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12126 hr = IDirect3DDevice9_EndScene(device);
12127 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12129 color = getPixelColor(device, 160, 360);
12130 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
12131 color = getPixelColor(device, 480, 360);
12132 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
12133 color = getPixelColor(device, 480, 120);
12134 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
12135 color = getPixelColor(device, 160, 120);
12136 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
12137 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12138 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
12140 cleanup:
12141 if(src) IDirect3DSurface9_Release(src);
12142 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
12143 if(dsttex) IDirect3DTexture9_Release(dsttex);
12144 refcount = IDirect3DDevice9_Release(device);
12145 ok(!refcount, "Device has %u references left.\n", refcount);
12146 done:
12147 IDirect3D9_Release(d3d);
12148 DestroyWindow(window);
12151 static void texop_test(void)
12153 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
12154 IDirect3DTexture9 *texture = NULL;
12155 D3DLOCKED_RECT locked_rect;
12156 IDirect3DDevice9 *device;
12157 IDirect3D9 *d3d;
12158 D3DCOLOR color;
12159 ULONG refcount;
12160 D3DCAPS9 caps;
12161 HWND window;
12162 HRESULT hr;
12163 unsigned i;
12165 static const struct {
12166 float x, y, z;
12167 float s, t;
12168 D3DCOLOR diffuse;
12169 } quad[] = {
12170 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
12171 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
12172 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
12173 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
12176 static const D3DVERTEXELEMENT9 decl_elements[] = {
12177 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
12178 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
12179 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
12180 D3DDECL_END()
12183 static const struct {
12184 D3DTEXTUREOP op;
12185 const char *name;
12186 DWORD caps_flag;
12187 D3DCOLOR result;
12188 } test_data[] = {
12189 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
12190 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
12191 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
12192 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
12193 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
12194 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
12195 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
12196 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
12197 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
12198 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
12199 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
12200 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
12201 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
12202 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
12203 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
12204 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
12205 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
12206 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
12207 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
12208 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
12209 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT3", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
12210 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
12211 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
12214 window = create_window();
12215 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12216 ok(!!d3d, "Failed to create a D3D object.\n");
12217 if (!(device = create_device(d3d, window, window, TRUE)))
12219 skip("Failed to create a D3D device, skipping tests.\n");
12220 goto done;
12223 memset(&caps, 0, sizeof(caps));
12224 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12225 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
12227 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
12228 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
12229 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
12230 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
12232 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
12233 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
12234 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
12235 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
12236 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
12237 hr = IDirect3DTexture9_UnlockRect(texture, 0);
12238 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
12239 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
12240 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
12242 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
12243 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12244 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12245 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12246 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12247 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12249 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
12250 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12252 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12253 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12254 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
12255 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12256 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
12257 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12259 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12260 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12262 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
12264 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
12266 skip("tex operation %s not supported\n", test_data[i].name);
12267 continue;
12270 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
12271 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
12273 hr = IDirect3DDevice9_BeginScene(device);
12274 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
12276 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12277 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
12279 hr = IDirect3DDevice9_EndScene(device);
12280 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
12282 color = getPixelColor(device, 320, 240);
12283 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
12284 test_data[i].name, color, test_data[i].result);
12286 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12287 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12290 IDirect3DTexture9_Release(texture);
12291 IDirect3DVertexDeclaration9_Release(vertex_declaration);
12292 refcount = IDirect3DDevice9_Release(device);
12293 ok(!refcount, "Device has %u references left.\n", refcount);
12294 done:
12295 IDirect3D9_Release(d3d);
12296 DestroyWindow(window);
12299 static void yuv_color_test(void)
12301 HRESULT hr;
12302 IDirect3DSurface9 *surface, *target;
12303 unsigned int i;
12304 D3DLOCKED_RECT lr;
12305 IDirect3D9 *d3d;
12306 D3DCOLOR color;
12307 D3DFORMAT skip_once = D3DFMT_UNKNOWN;
12308 IDirect3DDevice9 *device;
12309 D3DSURFACE_DESC desc;
12310 ULONG refcount;
12311 HWND window;
12313 static const struct
12315 DWORD in;
12316 D3DFORMAT format;
12317 const char *fmt_string;
12318 D3DCOLOR left, right;
12320 test_data[] =
12322 {0x00000000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00008700, 0x00008700},
12323 {0xff000000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00008700, 0x004bff1c},
12324 {0x00ff0000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b30000, 0x00b30000},
12325 {0x0000ff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bff1c, 0x00008700},
12326 {0x000000ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000030e1, 0x000030e1},
12327 {0xffff0000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b30000, 0x00ffd01c},
12328 {0xff00ff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bff1c, 0x004bff1c},
12329 {0xff0000ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000030e1, 0x004bffff},
12330 {0x00ffff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffd01c, 0x00b30000},
12331 {0x00ff00ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b300e1, 0x00b300e1},
12332 {0x0000ffff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bffff, 0x001030e1},
12333 {0xffffff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffd01c, 0x00ffd01c},
12334 {0xffff00ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b300e1, 0x00ff79ff},
12335 {0xffffffff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ff79ff, 0x00ff79ff},
12336 {0x4cff4c54, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ff0000, 0x00ff0000},
12337 {0x00800080, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00000000, 0x00000000},
12338 {0xff80ff80, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffffff, 0x00ffffff},
12339 {0x1c6b1cff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000000fd, 0x000000fd},
12341 {0x00000000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00008700, 0x00008700},
12342 {0xff000000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b30000, 0x00b30000},
12343 {0x00ff0000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00008700, 0x004bff1c},
12344 {0x0000ff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000030e1, 0x000030e1},
12345 {0x000000ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bff1c, 0x00008700},
12346 {0xffff0000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b30000, 0x00ffd01c},
12347 {0xff00ff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b300e1, 0x00b300e1},
12348 {0xff0000ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ffd01c, 0x00b30000},
12349 {0x00ffff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000030e1, 0x004bffff},
12350 {0x00ff00ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bff1c, 0x004bff1c},
12351 {0x0000ffff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bffff, 0x000030e1},
12352 {0xffffff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b300e1, 0x00ff79ff},
12353 {0xffff00ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ffd01c, 0x00ffd01c},
12354 {0xffffffff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ff79ff, 0x00ff79ff},
12355 {0x4cff4c54, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000b8b00, 0x00b6ffa3},
12356 {0x00800080, D3DFMT_YUY2, "D3DFMT_YUY2", 0x0000ff00, 0x0000ff00},
12357 {0xff80ff80, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ff00ff, 0x00ff00ff},
12358 {0x1c6b1cff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x006dff45, 0x0000d500},
12361 window = create_window();
12362 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12363 ok(!!d3d, "Failed to create a D3D object.\n");
12364 if (!(device = create_device(d3d, window, window, TRUE)))
12366 skip("Failed to create a D3D device, skipping tests.\n");
12367 goto done;
12370 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
12371 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
12372 hr = IDirect3DSurface9_GetDesc(target, &desc);
12373 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
12375 for (i = 0; i < sizeof(test_data) / sizeof(test_data[0]); i++)
12377 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect.
12378 * Thus use StretchRect to draw the YUV surface onto the screen instead of drawPrimitive. */
12379 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
12380 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, test_data[i].format)))
12382 if (skip_once != test_data[i].format)
12384 skip("%s is not supported.\n", test_data[i].fmt_string);
12385 skip_once = test_data[i].format;
12387 continue;
12389 if (FAILED(IDirect3D9_CheckDeviceFormatConversion(d3d, 0,
12390 D3DDEVTYPE_HAL, test_data[i].format, desc.Format)))
12392 if (skip_once != test_data[i].format)
12394 skip("Driver cannot blit %s surfaces.\n", test_data[i].fmt_string);
12395 skip_once = test_data[i].format;
12397 continue;
12400 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1.
12401 * However, Nvidia Windows drivers have problems with 2x1 YUY2/UYVY surfaces, so use a 4x1 surface and
12402 * fill the second block with dummy data. If the surface has a size of 2x1, those drivers ignore the
12403 * second luminance value, resulting in an incorrect color in the right pixel. */
12404 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 1, test_data[i].format,
12405 D3DPOOL_DEFAULT, &surface, NULL);
12406 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
12409 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
12410 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
12411 ((DWORD *)lr.pBits)[0] = test_data[i].in;
12412 ((DWORD *)lr.pBits)[1] = 0x00800080;
12413 hr = IDirect3DSurface9_UnlockRect(surface);
12414 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
12416 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
12417 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
12418 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
12419 ok(SUCCEEDED(hr), "Failed to draw surface onto backbuffer, hr %#x.\n", hr);
12421 /* Some Windows drivers (mostly Nvidia, but also some VM drivers) insist on doing linear filtering
12422 * although we asked for point filtering. Be careful when reading the results and use the pixel
12423 * centers. In the future we may want to add tests for the filtered pixels as well.
12425 * Unfortunately different implementations(Windows-Nvidia and Mac-AMD tested) interpret some colors
12426 * vastly differently, so we need a max diff of 18. */
12427 color = getPixelColor(device, 1, 240);
12428 ok(color_match(color, test_data[i].left, 18),
12429 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s.\n",
12430 test_data[i].in, color, test_data[i].left, test_data[i].fmt_string);
12431 color = getPixelColor(device, 318, 240);
12432 ok(color_match(color, test_data[i].right, 18),
12433 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s.\n",
12434 test_data[i].in, color, test_data[i].right, test_data[i].fmt_string);
12435 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12436 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
12437 IDirect3DSurface9_Release(surface);
12440 IDirect3DSurface9_Release(target);
12441 refcount = IDirect3DDevice9_Release(device);
12442 ok(!refcount, "Device has %u references left.\n", refcount);
12443 done:
12444 IDirect3D9_Release(d3d);
12445 DestroyWindow(window);
12448 static void yuv_layout_test(void)
12450 HRESULT hr;
12451 IDirect3DSurface9 *surface, *target;
12452 unsigned int fmt, i, x, y;
12453 D3DFORMAT format;
12454 const char *fmt_string;
12455 D3DLOCKED_RECT lr;
12456 IDirect3D9 *d3d;
12457 D3DCOLOR color;
12458 DWORD ref_color;
12459 BYTE *buf, *chroma_buf, *u_buf, *v_buf;
12460 UINT width = 20, height = 16;
12461 IDirect3DDevice9 *device;
12462 ULONG refcount;
12463 D3DCAPS9 caps;
12464 D3DSURFACE_DESC desc;
12465 HWND window;
12467 static const struct
12469 DWORD color1, color2;
12470 DWORD rgb1, rgb2;
12472 test_data[] =
12474 { 0x000000, 0xffffff, 0x00008800, 0x00ff7dff },
12475 { 0xff0000, 0x00ffff, 0x004aff14, 0x00b800ee },
12476 { 0x00ff00, 0xff00ff, 0x000024ee, 0x00ffe114 },
12477 { 0x0000ff, 0xffff00, 0x00b80000, 0x004affff },
12478 { 0xffff00, 0x0000ff, 0x004affff, 0x00b80000 },
12479 { 0xff00ff, 0x00ff00, 0x00ffe114, 0x000024ee },
12480 { 0x00ffff, 0xff0000, 0x00b800ee, 0x004aff14 },
12481 { 0xffffff, 0x000000, 0x00ff7dff, 0x00008800 },
12484 static const struct
12486 D3DFORMAT format;
12487 const char *str;
12489 formats[] =
12491 { D3DFMT_UYVY, "D3DFMT_UYVY", },
12492 { D3DFMT_YUY2, "D3DFMT_YUY2", },
12493 { MAKEFOURCC('Y','V','1','2'), "D3DFMT_YV12", },
12494 { MAKEFOURCC('N','V','1','2'), "D3DFMT_NV12", },
12497 window = create_window();
12498 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12499 ok(!!d3d, "Failed to create a D3D object.\n");
12500 if (!(device = create_device(d3d, window, window, TRUE)))
12502 skip("Failed to create a D3D device, skipping tests.\n");
12503 goto done;
12506 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12507 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
12508 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2
12509 && !(caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL))
12511 skip("No NP2 texture support, skipping YUV texture layout test.\n");
12512 IDirect3DDevice9_Release(device);
12513 goto done;
12516 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
12517 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %#x.\n", hr);
12518 hr = IDirect3DSurface9_GetDesc(target, &desc);
12519 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
12521 for (fmt = 0; fmt < sizeof(formats) / sizeof(formats[0]); fmt++)
12523 format = formats[fmt].format;
12524 fmt_string = formats[fmt].str;
12526 /* Some (all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in
12527 * StretchRect. Thus use StretchRect to draw the YUV surface onto the screen instead
12528 * of drawPrimitive. */
12529 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
12530 D3DRTYPE_SURFACE, format) != D3D_OK)
12532 skip("%s is not supported.\n", fmt_string);
12533 continue;
12535 if (FAILED(IDirect3D9_CheckDeviceFormatConversion(d3d, 0,
12536 D3DDEVTYPE_HAL, format, desc.Format)))
12538 skip("Driver cannot blit %s surfaces.\n", fmt_string);
12539 continue;
12542 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, width, height, format, D3DPOOL_DEFAULT, &surface, NULL);
12543 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %#x.\n", hr);
12545 for (i = 0; i < sizeof(test_data) / sizeof(test_data[0]); i++)
12547 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
12548 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %#x.\n", hr);
12549 buf = lr.pBits;
12550 chroma_buf = buf + lr.Pitch * height;
12551 if (format == MAKEFOURCC('Y','V','1','2'))
12553 v_buf = chroma_buf;
12554 u_buf = chroma_buf + height / 2 * lr.Pitch/2;
12556 /* Draw the top left quarter of the screen with color1, the rest with color2 */
12557 for (y = 0; y < height; y++)
12559 for (x = 0; x < width; x += 2)
12561 DWORD color = (x < width / 2 && y < height / 2) ? test_data[i].color1 : test_data[i].color2;
12562 BYTE Y = (color >> 16) & 0xff;
12563 BYTE U = (color >> 8) & 0xff;
12564 BYTE V = (color >> 0) & 0xff;
12565 if (format == D3DFMT_UYVY)
12567 buf[y * lr.Pitch + 2 * x + 0] = U;
12568 buf[y * lr.Pitch + 2 * x + 1] = Y;
12569 buf[y * lr.Pitch + 2 * x + 2] = V;
12570 buf[y * lr.Pitch + 2 * x + 3] = Y;
12572 else if (format == D3DFMT_YUY2)
12574 buf[y * lr.Pitch + 2 * x + 0] = Y;
12575 buf[y * lr.Pitch + 2 * x + 1] = U;
12576 buf[y * lr.Pitch + 2 * x + 2] = Y;
12577 buf[y * lr.Pitch + 2 * x + 3] = V;
12579 else if (format == MAKEFOURCC('Y','V','1','2'))
12581 buf[y * lr.Pitch + x + 0] = Y;
12582 buf[y * lr.Pitch + x + 1] = Y;
12583 u_buf[(y / 2) * (lr.Pitch / 2) + (x / 2)] = U;
12584 v_buf[(y / 2) * (lr.Pitch / 2) + (x / 2)] = V;
12586 else if (format == MAKEFOURCC('N','V','1','2'))
12588 buf[y * lr.Pitch + x + 0] = Y;
12589 buf[y * lr.Pitch + x + 1] = Y;
12590 chroma_buf[(y / 2) * lr.Pitch + 2 * (x / 2) + 0] = U;
12591 chroma_buf[(y / 2) * lr.Pitch + 2 * (x / 2) + 1] = V;
12595 hr = IDirect3DSurface9_UnlockRect(surface);
12596 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %#x.\n", hr);
12598 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
12599 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %#x.\n", hr);
12600 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
12601 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %#x.\n", hr);
12603 /* Some Windows drivers (mostly Nvidia, but also some VM drivers) insist on doing linear filtering
12604 * although we asked for point filtering. To prevent running into precision problems, read at points
12605 * with some margin within each quadrant.
12607 * Unfortunately different implementations(Windows-Nvidia and Mac-AMD tested) interpret some colors
12608 * vastly differently, so we need a max diff of 18. */
12609 for (y = 0; y < 4; y++)
12611 for (x = 0; x < 4; x++)
12613 UINT xcoord = (1 + 2 * x) * 640 / 8;
12614 UINT ycoord = (1 + 2 * y) * 480 / 8;
12615 ref_color = (y < 2 && x < 2) ? test_data[i].rgb1 : test_data[i].rgb2;
12616 color = getPixelColor(device, xcoord, ycoord);
12617 ok(color_match(color, ref_color, 18),
12618 "Format %s: Got color %#x for pixel (%d/%d)/(%d/%d), pixel %d %d, expected %#x.\n",
12619 fmt_string, color, x, 4, y, 4, xcoord, ycoord, ref_color);
12622 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12624 ok(SUCCEEDED(hr), "Present failed with %#x.\n", hr);
12626 IDirect3DSurface9_Release(surface);
12629 IDirect3DSurface9_Release(target);
12630 refcount = IDirect3DDevice9_Release(device);
12631 ok(!refcount, "Device has %u references left.\n", refcount);
12632 done:
12633 IDirect3D9_Release(d3d);
12634 DestroyWindow(window);
12637 static void texop_range_test(void)
12639 IDirect3DTexture9 *texture;
12640 D3DLOCKED_RECT locked_rect;
12641 IDirect3DDevice9 *device;
12642 IDirect3D9 *d3d;
12643 ULONG refcount;
12644 D3DCAPS9 caps;
12645 DWORD color;
12646 HWND window;
12647 HRESULT hr;
12649 static const struct
12651 float x, y, z;
12652 D3DCOLOR diffuse;
12654 quad[] =
12656 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
12657 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
12658 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
12659 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
12662 window = create_window();
12663 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12664 ok(!!d3d, "Failed to create a D3D object.\n");
12665 if (!(device = create_device(d3d, window, window, TRUE)))
12667 skip("Failed to create a D3D device, skipping tests.\n");
12668 goto done;
12671 /* We need ADD and SUBTRACT operations */
12672 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12673 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
12674 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD))
12676 skip("D3DTOP_ADD is not supported, skipping value range test.\n");
12677 IDirect3DDevice9_Release(device);
12678 goto done;
12680 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT))
12682 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test.\n");
12683 IDirect3DDevice9_Release(device);
12684 goto done;
12687 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12688 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
12689 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12690 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
12691 /* Stage 1: result = diffuse(=1.0) + diffuse
12692 * stage 2: result = result - tfactor(= 0.5)
12694 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12695 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12696 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
12697 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12698 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
12699 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12700 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
12701 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12702 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
12703 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12704 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12705 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12706 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
12707 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12709 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12710 ok(SUCCEEDED(hr), "Failed to clear device, hr %#x.\n\n", hr);
12711 hr = IDirect3DDevice9_BeginScene(device);
12712 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
12713 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12714 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
12715 hr = IDirect3DDevice9_EndScene(device);
12716 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
12718 color = getPixelColor(device, 320, 240);
12719 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
12720 color);
12721 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12722 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12724 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
12725 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
12726 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
12727 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
12728 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
12729 hr = IDirect3DTexture9_UnlockRect(texture, 0);
12730 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
12731 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
12732 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
12734 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
12735 * stage 2: result = result + diffuse(1.0)
12737 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12738 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12739 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12740 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12741 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12742 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12743 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
12744 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12745 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
12746 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12747 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
12748 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12749 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
12750 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12752 hr = IDirect3DDevice9_BeginScene(device);
12753 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
12754 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12755 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
12756 hr = IDirect3DDevice9_EndScene(device);
12757 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
12759 color = getPixelColor(device, 320, 240);
12760 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
12761 color);
12762 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12763 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12765 IDirect3DTexture9_Release(texture);
12766 refcount = IDirect3DDevice9_Release(device);
12767 ok(!refcount, "Device has %u references left.\n", refcount);
12768 done:
12769 IDirect3D9_Release(d3d);
12770 DestroyWindow(window);
12773 static void alphareplicate_test(void)
12775 IDirect3DDevice9 *device;
12776 IDirect3D9 *d3d;
12777 ULONG refcount;
12778 DWORD color;
12779 HWND window;
12780 HRESULT hr;
12782 static const struct
12784 struct vec3 position;
12785 DWORD diffuse;
12787 quad[] =
12789 {{-1.0f, -1.0f, 0.1f}, 0x80ff00ff},
12790 {{-1.0f, 1.0f, 0.1f}, 0x80ff00ff},
12791 {{ 1.0f, -1.0f, 0.1f}, 0x80ff00ff},
12792 {{ 1.0f, 1.0f, 0.1f}, 0x80ff00ff},
12795 window = create_window();
12796 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12797 ok(!!d3d, "Failed to create a D3D object.\n");
12798 if (!(device = create_device(d3d, window, window, TRUE)))
12800 skip("Failed to create a D3D device, skipping tests.\n");
12801 goto done;
12804 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12805 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12807 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12808 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12810 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12811 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12812 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
12813 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12815 hr = IDirect3DDevice9_BeginScene(device);
12816 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12817 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12818 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12819 hr = IDirect3DDevice9_EndScene(device);
12820 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12822 color = getPixelColor(device, 320, 240);
12823 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
12824 color);
12825 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12826 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12828 refcount = IDirect3DDevice9_Release(device);
12829 ok(!refcount, "Device has %u references left.\n", refcount);
12830 done:
12831 IDirect3D9_Release(d3d);
12832 DestroyWindow(window);
12835 static void dp3_alpha_test(void)
12837 IDirect3DDevice9 *device;
12838 IDirect3D9 *d3d;
12839 ULONG refcount;
12840 D3DCAPS9 caps;
12841 DWORD color;
12842 HWND window;
12843 HRESULT hr;
12845 static const struct
12847 struct vec3 position;
12848 DWORD diffuse;
12850 quad[] =
12852 {{-1.0f, -1.0f, 0.1f}, 0x408080c0},
12853 {{-1.0f, 1.0f, 0.1f}, 0x408080c0},
12854 {{ 1.0f, -1.0f, 0.1f}, 0x408080c0},
12855 {{ 1.0f, 1.0f, 0.1f}, 0x408080c0},
12858 window = create_window();
12859 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12860 ok(!!d3d, "Failed to create a D3D object.\n");
12861 if (!(device = create_device(d3d, window, window, TRUE)))
12863 skip("Failed to create a D3D device, skipping tests.\n");
12864 goto done;
12867 memset(&caps, 0, sizeof(caps));
12868 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12869 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
12870 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3))
12872 skip("D3DTOP_DOTPRODUCT3 not supported\n");
12873 IDirect3DDevice9_Release(device);
12874 goto done;
12877 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12878 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12880 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12881 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12883 /* dp3_x4 r0, diffuse_bias, tfactor_bias
12884 * mov r0.a, diffuse.a
12885 * mov r0, r0.a
12887 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
12888 * 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
12889 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
12891 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
12892 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12893 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
12894 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12895 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12896 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12897 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
12898 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12899 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
12900 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12901 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12902 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12903 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
12904 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12905 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
12906 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12907 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
12908 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12909 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12910 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
12912 hr = IDirect3DDevice9_BeginScene(device);
12913 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12914 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12915 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12916 hr = IDirect3DDevice9_EndScene(device);
12917 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12919 color = getPixelColor(device, 320, 240);
12920 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
12921 color);
12922 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12923 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12925 refcount = IDirect3DDevice9_Release(device);
12926 ok(!refcount, "Device has %u references left.\n", refcount);
12927 done:
12928 IDirect3D9_Release(d3d);
12929 DestroyWindow(window);
12932 static void zwriteenable_test(void)
12934 IDirect3DDevice9 *device;
12935 IDirect3D9 *d3d;
12936 D3DCOLOR color;
12937 ULONG refcount;
12938 HWND window;
12939 HRESULT hr;
12941 static const struct
12943 struct vec3 position;
12944 DWORD diffuse;
12946 quad1[] =
12948 {{-1.0f, -1.0f, 0.1f}, 0x00ff0000},
12949 {{-1.0f, 1.0f, 0.1f}, 0x00ff0000},
12950 {{ 1.0f, -1.0f, 0.1f}, 0x00ff0000},
12951 {{ 1.0f, 1.0f, 0.1f}, 0x00ff0000},
12953 quad2[] =
12955 {{-1.0f, -1.0f, 0.9f}, 0x0000ff00},
12956 {{-1.0f, 1.0f, 0.9f}, 0x0000ff00},
12957 {{ 1.0f, -1.0f, 0.9f}, 0x0000ff00},
12958 {{ 1.0f, 1.0f, 0.9f}, 0x0000ff00},
12961 window = create_window();
12962 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12963 ok(!!d3d, "Failed to create a D3D object.\n");
12964 if (!(device = create_device(d3d, window, window, TRUE)))
12966 skip("Failed to create a D3D device, skipping tests.\n");
12967 goto done;
12970 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
12971 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12973 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12974 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12975 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12976 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12977 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12978 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12979 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
12980 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12981 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12982 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
12984 hr = IDirect3DDevice9_BeginScene(device);
12985 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12986 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1,
12987 * zenable = D3DZB_FALSE, zwriteenable = TRUE. The red color is written
12988 * because the z test is disabled. The question is whether the z = 0.1
12989 * values are written into the Z buffer. After the draw, set
12990 * zenable = TRUE and draw a green quad at z = 0.9. If the values are
12991 * written, the z test will fail(0.9 > 0.1) and the red color remains. If
12992 * the values are not written, the z test succeeds(0.9 < 1.0) and the
12993 * green color is written. It turns out that the screen is green, so
12994 * zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z
12995 * buffer. */
12996 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
12997 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12998 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12999 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
13000 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13001 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13002 hr = IDirect3DDevice9_EndScene(device);
13003 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13005 color = getPixelColor(device, 320, 240);
13006 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
13007 color);
13008 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13009 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
13011 refcount = IDirect3DDevice9_Release(device);
13012 ok(!refcount, "Device has %u references left.\n", refcount);
13013 done:
13014 IDirect3D9_Release(d3d);
13015 DestroyWindow(window);
13018 static void alphatest_test(void)
13020 #define ALPHATEST_PASSED 0x0000ff00
13021 #define ALPHATEST_FAILED 0x00ff0000
13022 IDirect3DDevice9 *device;
13023 unsigned int i, j;
13024 IDirect3D9 *d3d;
13025 D3DCOLOR color;
13026 ULONG refcount;
13027 D3DCAPS9 caps;
13028 HWND window;
13029 HRESULT hr;
13031 static const struct
13033 D3DCMPFUNC func;
13034 D3DCOLOR color_less;
13035 D3DCOLOR color_equal;
13036 D3DCOLOR color_greater;
13038 testdata[] =
13040 {D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED},
13041 {D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED},
13042 {D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED},
13043 {D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED},
13044 {D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED},
13045 {D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED},
13046 {D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED},
13047 {D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED},
13049 static const struct
13051 struct vec3 position;
13052 DWORD diffuse;
13054 quad[] =
13056 {{-1.0f, -1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
13057 {{-1.0f, 1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
13058 {{ 1.0f, -1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
13059 {{ 1.0f, 1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
13062 window = create_window();
13063 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13064 ok(!!d3d, "Failed to create a D3D object.\n");
13065 if (!(device = create_device(d3d, window, window, TRUE)))
13067 skip("Failed to create a D3D device, skipping tests.\n");
13068 goto done;
13071 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
13072 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
13074 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13075 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
13076 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
13077 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
13078 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13079 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
13081 for (j = 0; j < 2; ++j)
13083 if (j == 1)
13085 /* Try a pixel shader instead of fixed function. The wined3d code
13086 * may emulate the alpha test either for performance reasons
13087 * (floating point RTs) or to work around driver bugs (GeForce
13088 * 7x00 cards on MacOS). There may be a different codepath for ffp
13089 * and shader in this case, and the test should cover both. */
13090 IDirect3DPixelShader9 *ps;
13091 static const DWORD shader_code[] =
13093 0xffff0101, /* ps_1_1 */
13094 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
13095 0x0000ffff /* end */
13097 memset(&caps, 0, sizeof(caps));
13098 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13099 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
13100 if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
13101 break;
13104 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
13105 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
13106 hr = IDirect3DDevice9_SetPixelShader(device, ps);
13107 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
13108 IDirect3DPixelShader9_Release(ps);
13111 for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
13112 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
13113 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
13115 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
13116 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
13117 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
13118 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
13119 hr = IDirect3DDevice9_BeginScene(device);
13120 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13121 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13122 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13123 hr = IDirect3DDevice9_EndScene(device);
13124 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13125 color = getPixelColor(device, 320, 240);
13126 ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
13127 color, testdata[i].color_less, testdata[i].func);
13128 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13129 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
13131 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
13132 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
13133 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
13134 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
13135 hr = IDirect3DDevice9_BeginScene(device);
13136 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13137 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13138 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13139 hr = IDirect3DDevice9_EndScene(device);
13140 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13141 color = getPixelColor(device, 320, 240);
13142 ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
13143 color, testdata[i].color_equal, testdata[i].func);
13144 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13145 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
13147 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
13148 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
13149 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
13150 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
13151 hr = IDirect3DDevice9_BeginScene(device);
13152 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13153 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13154 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13155 hr = IDirect3DDevice9_EndScene(device);
13156 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13157 color = getPixelColor(device, 320, 240);
13158 ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
13159 color, testdata[i].color_greater, testdata[i].func);
13160 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13161 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
13165 refcount = IDirect3DDevice9_Release(device);
13166 ok(!refcount, "Device has %u references left.\n", refcount);
13167 done:
13168 IDirect3D9_Release(d3d);
13169 DestroyWindow(window);
13172 static void sincos_test(void)
13174 IDirect3DVertexShader9 *sin_shader, *cos_shader;
13175 IDirect3DDevice9 *device;
13176 struct vec3 data[1280];
13177 IDirect3D9 *d3d;
13178 unsigned int i;
13179 ULONG refcount;
13180 D3DCAPS9 caps;
13181 HWND window;
13182 HRESULT hr;
13184 static const DWORD sin_shader_code[] =
13186 0xfffe0200, /* vs_2_0 */
13187 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
13188 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
13189 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
13190 0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.y, r1.x, c0, c1 */
13191 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
13192 0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002, /* mul oPos.y, r0.y, c2.w */
13193 0x02000001, 0xd00f0000, 0xa0a60002, /* mov oD0, c2.zyzz */
13194 0x0000ffff /* end */
13196 static const DWORD cos_shader_code[] =
13198 0xfffe0200, /* vs_2_0 */
13199 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
13200 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
13201 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
13202 0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.x, r1.x, c0, c1 */
13203 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
13204 0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002, /* mul oPos.y, r0.x, c2.w */
13205 0x02000001, 0xd00f0000, 0xa0a90002, /* mov oD0, c2.yzzz */
13206 0x0000ffff /* end */
13208 static const float sincosc1[4] = {D3DSINCOSCONST1};
13209 static const float sincosc2[4] = {D3DSINCOSCONST2};
13211 window = create_window();
13212 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13213 ok(!!d3d, "Failed to create a D3D object.\n");
13214 if (!(device = create_device(d3d, window, window, TRUE)))
13216 skip("Failed to create a D3D device, skipping tests.\n");
13217 goto done;
13220 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13221 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13222 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
13224 skip("No vs_2_0 support, skipping tests.\n");
13225 IDirect3DDevice9_Release(device);
13226 goto done;
13229 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
13230 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
13232 hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
13233 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
13234 hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
13235 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
13236 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13237 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
13238 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
13239 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
13240 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
13241 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
13243 /* Generate a point from -1 to 1 every 0.5 pixels */
13244 for(i = 0; i < 1280; i++) {
13245 data[i].x = (-640.0 + i) / 640.0;
13246 data[i].y = 0.0;
13247 data[i].z = 0.1;
13250 hr = IDirect3DDevice9_BeginScene(device);
13251 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13253 hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
13254 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
13255 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
13256 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13258 hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
13259 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
13260 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
13261 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13263 hr = IDirect3DDevice9_EndScene(device);
13264 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13266 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13267 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
13268 /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
13270 IDirect3DVertexShader9_Release(sin_shader);
13271 IDirect3DVertexShader9_Release(cos_shader);
13272 refcount = IDirect3DDevice9_Release(device);
13273 ok(!refcount, "Device has %u references left.\n", refcount);
13274 done:
13275 IDirect3D9_Release(d3d);
13276 DestroyWindow(window);
13279 static void loop_index_test(void)
13281 IDirect3DVertexShader9 *shader;
13282 IDirect3DDevice9 *device;
13283 IDirect3D9 *d3d;
13284 float values[4];
13285 ULONG refcount;
13286 D3DCAPS9 caps;
13287 DWORD color;
13288 HWND window;
13289 HRESULT hr;
13291 static const DWORD shader_code[] =
13293 0xfffe0200, /* vs_2_0 */
13294 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
13295 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
13296 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
13297 0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1] */
13298 0x0000001d, /* endloop */
13299 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
13300 0x02000001, 0xd00f0000, 0x80e40000, /* mov oD0, r0 */
13301 0x0000ffff /* END */
13303 static const float quad[] =
13305 -1.0f, -1.0f, 0.1f,
13306 -1.0f, 1.0f, 0.1f,
13307 1.0f, -1.0f, 0.1f,
13308 1.0f, 1.0f, 0.1f,
13310 static const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
13311 static const float one[4] = {1.0f, 1.0f, 1.0f, 1.0f};
13312 static const int i0[4] = {2, 10, -3, 0};
13314 window = create_window();
13315 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13316 ok(!!d3d, "Failed to create a D3D object.\n");
13317 if (!(device = create_device(d3d, window, window, TRUE)))
13319 skip("Failed to create a D3D device, skipping tests.\n");
13320 goto done;
13323 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13324 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13325 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
13327 skip("No vs_2_0 support, skipping tests.\n");
13328 IDirect3DDevice9_Release(device);
13329 goto done;
13332 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
13333 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
13334 hr = IDirect3DDevice9_SetVertexShader(device, shader);
13335 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
13336 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13337 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
13338 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
13339 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
13341 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
13342 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13343 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
13344 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13345 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
13346 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13347 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
13348 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13349 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
13350 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13351 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
13352 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13353 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
13354 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13355 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
13356 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13357 values[0] = 1.0;
13358 values[1] = 1.0;
13359 values[2] = 0.0;
13360 values[3] = 0.0;
13361 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
13362 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13363 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
13364 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13365 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
13366 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13367 values[0] = -1.0;
13368 values[1] = 0.0;
13369 values[2] = 0.0;
13370 values[3] = 0.0;
13371 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
13372 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13373 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
13374 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13375 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
13376 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13377 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
13378 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13379 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
13380 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13382 hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
13383 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
13385 hr = IDirect3DDevice9_BeginScene(device);
13386 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13387 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
13388 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13389 hr = IDirect3DDevice9_EndScene(device);
13390 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13391 color = getPixelColor(device, 320, 240);
13392 ok(color_match(color, 0x0000ff00, 1),
13393 "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
13394 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13395 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
13397 IDirect3DVertexShader9_Release(shader);
13398 refcount = IDirect3DDevice9_Release(device);
13399 ok(!refcount, "Device has %u references left.\n", refcount);
13400 done:
13401 IDirect3D9_Release(d3d);
13402 DestroyWindow(window);
13405 static void sgn_test(void)
13407 IDirect3DVertexShader9 *shader;
13408 IDirect3DDevice9 *device;
13409 IDirect3D9 *d3d;
13410 ULONG refcount;
13411 D3DCAPS9 caps;
13412 DWORD color;
13413 HWND window;
13414 HRESULT hr;
13416 static const DWORD shader_code[] =
13418 0xfffe0200, /* vs_2_0 */
13419 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position o0 */
13420 0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
13421 0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0 */
13422 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
13423 0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002, /* sgn r0, c0, r1, r2 */
13424 0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001, /* add oD0, r0, c1 */
13425 0x0000ffff /* end */
13427 static const float quad[] =
13429 -1.0f, -1.0f, 0.1f,
13430 -1.0f, 1.0f, 0.1f,
13431 1.0f, -1.0f, 0.1f,
13432 1.0f, 1.0f, 0.1f,
13435 window = create_window();
13436 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13437 ok(!!d3d, "Failed to create a D3D object.\n");
13438 if (!(device = create_device(d3d, window, window, TRUE)))
13440 skip("Failed to create a D3D device, skipping tests.\n");
13441 goto done;
13444 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13445 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13446 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
13448 skip("No vs_2_0 support, skipping tests.\n");
13449 IDirect3DDevice9_Release(device);
13450 goto done;
13453 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
13454 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
13455 hr = IDirect3DDevice9_SetVertexShader(device, shader);
13456 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
13457 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13458 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
13459 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
13460 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
13462 hr = IDirect3DDevice9_BeginScene(device);
13463 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13464 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
13465 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13466 hr = IDirect3DDevice9_EndScene(device);
13467 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13468 color = getPixelColor(device, 320, 240);
13469 ok(color_match(color, 0x008000ff, 1),
13470 "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
13471 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13472 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
13474 IDirect3DVertexShader9_Release(shader);
13475 refcount = IDirect3DDevice9_Release(device);
13476 ok(!refcount, "Device has %u references left.\n", refcount);
13477 done:
13478 IDirect3D9_Release(d3d);
13479 DestroyWindow(window);
13482 static void viewport_test(void)
13484 IDirect3DDevice9 *device;
13485 BOOL draw_failed = TRUE;
13486 D3DVIEWPORT9 vp;
13487 IDirect3D9 *d3d;
13488 ULONG refcount;
13489 DWORD color;
13490 HWND window;
13491 HRESULT hr;
13493 static const float quad[] =
13495 -0.5f, -0.5f, 0.1f,
13496 -0.5f, 0.5f, 0.1f,
13497 0.5f, -0.5f, 0.1f,
13498 0.5f, 0.5f, 0.1f,
13501 window = create_window();
13502 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13503 ok(!!d3d, "Failed to create a D3D object.\n");
13504 if (!(device = create_device(d3d, window, window, TRUE)))
13506 skip("Failed to create a D3D device, skipping tests.\n");
13507 goto done;
13510 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
13511 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
13513 /* Test a viewport with Width and Height bigger than the surface dimensions
13515 * TODO: Test Width < surface.width, but X + Width > surface.width
13516 * TODO: Test Width < surface.width, what happens with the height?
13518 * The expected behavior is that the viewport behaves like the "default"
13519 * viewport with X = Y = 0, Width = surface_width, Height = surface_height,
13520 * MinZ = 0.0, MaxZ = 1.0.
13522 * Starting with Windows 7 the behavior among driver versions is not
13523 * consistent. The SetViewport call is accepted on all drivers. Some
13524 * drivers(older nvidia ones) refuse to draw and return an error. Newer
13525 * nvidia drivers draw, but use the actual values in the viewport and only
13526 * display the upper left part on the surface.
13528 memset(&vp, 0, sizeof(vp));
13529 vp.X = 0;
13530 vp.Y = 0;
13531 vp.Width = 10000;
13532 vp.Height = 10000;
13533 vp.MinZ = 0.0;
13534 vp.MaxZ = 0.0;
13535 hr = IDirect3DDevice9_SetViewport(device, &vp);
13536 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
13538 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13539 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
13541 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13542 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
13543 hr = IDirect3DDevice9_BeginScene(device);
13544 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13545 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
13546 ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
13547 draw_failed = FAILED(hr);
13548 hr = IDirect3DDevice9_EndScene(device);
13549 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13551 if(!draw_failed)
13553 color = getPixelColor(device, 158, 118);
13554 ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
13555 color = getPixelColor(device, 162, 118);
13556 ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
13557 color = getPixelColor(device, 158, 122);
13558 ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
13559 color = getPixelColor(device, 162, 122);
13560 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (162,122) has color %08x\n", color);
13562 color = getPixelColor(device, 478, 358);
13563 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (478,358 has color %08x\n", color);
13564 color = getPixelColor(device, 482, 358);
13565 ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
13566 color = getPixelColor(device, 478, 362);
13567 ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
13568 color = getPixelColor(device, 482, 362);
13569 ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
13572 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13573 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
13575 refcount = IDirect3DDevice9_Release(device);
13576 ok(!refcount, "Device has %u references left.\n", refcount);
13577 done:
13578 IDirect3D9_Release(d3d);
13579 DestroyWindow(window);
13582 /* This test tests depth clamping / clipping behaviour:
13583 * - With software vertex processing, depth values are clamped to the
13584 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
13585 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
13586 * same as regular vertices here.
13587 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
13588 * Normal vertices are always clipped. Pretransformed vertices are
13589 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
13590 * - The viewport's MinZ/MaxZ is irrelevant for this.
13592 static void depth_clamp_test(void)
13594 IDirect3DDevice9 *device;
13595 D3DVIEWPORT9 vp;
13596 IDirect3D9 *d3d;
13597 D3DCOLOR color;
13598 ULONG refcount;
13599 D3DCAPS9 caps;
13600 HWND window;
13601 HRESULT hr;
13603 static const struct
13605 struct vec4 position;
13606 DWORD diffuse;
13608 quad1[] =
13610 {{ 0.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
13611 {{640.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
13612 {{ 0.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
13613 {{640.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
13615 quad2[] =
13617 {{ 0.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
13618 {{640.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
13619 {{ 0.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
13620 {{640.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
13622 quad3[] =
13624 {{112.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
13625 {{208.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
13626 {{112.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
13627 {{208.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
13629 quad4[] =
13631 {{ 42.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
13632 {{112.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
13633 {{ 42.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
13634 {{112.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
13636 static const struct
13638 struct vec3 position;
13639 DWORD diffuse;
13641 quad5[] =
13643 {{-0.5f, 0.5f, 10.0f}, 0xff14f914},
13644 {{ 0.5f, 0.5f, 10.0f}, 0xff14f914},
13645 {{-0.5f, -0.5f, 10.0f}, 0xff14f914},
13646 {{ 0.5f, -0.5f, 10.0f}, 0xff14f914},
13648 quad6[] =
13650 {{-1.0f, 0.5f, 10.0f}, 0xfff91414},
13651 {{ 1.0f, 0.5f, 10.0f}, 0xfff91414},
13652 {{-1.0f, 0.25f, 10.0f}, 0xfff91414},
13653 {{ 1.0f, 0.25f, 10.0f}, 0xfff91414},
13656 window = create_window();
13657 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13658 ok(!!d3d, "Failed to create a D3D object.\n");
13659 if (!(device = create_device(d3d, window, window, TRUE)))
13661 skip("Failed to create a D3D device, skipping tests.\n");
13662 goto done;
13665 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13666 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13668 vp.X = 0;
13669 vp.Y = 0;
13670 vp.Width = 640;
13671 vp.Height = 480;
13672 vp.MinZ = 0.0;
13673 vp.MaxZ = 7.5;
13675 hr = IDirect3DDevice9_SetViewport(device, &vp);
13676 if(FAILED(hr))
13678 /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
13679 * the tests because the 7.5 is just intended to show that it doesn't have
13680 * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
13681 * viewport and continue.
13683 ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
13684 vp.MaxZ = 1.0;
13685 hr = IDirect3DDevice9_SetViewport(device, &vp);
13687 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
13689 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
13690 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13692 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
13693 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13694 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13695 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13696 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13697 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13698 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13699 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13701 hr = IDirect3DDevice9_BeginScene(device);
13702 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13704 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
13705 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13707 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13708 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13709 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13710 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13712 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
13713 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13715 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
13716 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13717 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
13718 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13720 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
13721 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13723 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13724 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13726 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
13727 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13729 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
13730 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13732 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
13733 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13735 hr = IDirect3DDevice9_EndScene(device);
13736 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13738 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
13740 color = getPixelColor(device, 75, 75);
13741 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13742 color = getPixelColor(device, 150, 150);
13743 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13744 color = getPixelColor(device, 320, 240);
13745 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13746 color = getPixelColor(device, 320, 330);
13747 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13748 color = getPixelColor(device, 320, 330);
13749 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13751 else
13753 color = getPixelColor(device, 75, 75);
13754 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
13755 color = getPixelColor(device, 150, 150);
13756 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
13757 color = getPixelColor(device, 320, 240);
13758 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
13759 color = getPixelColor(device, 320, 330);
13760 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13761 color = getPixelColor(device, 320, 330);
13762 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13765 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13766 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13768 refcount = IDirect3DDevice9_Release(device);
13769 ok(!refcount, "Device has %u references left.\n", refcount);
13770 done:
13771 IDirect3D9_Release(d3d);
13772 DestroyWindow(window);
13775 static void depth_bounds_test(void)
13777 static const struct
13779 struct vec4 position;
13780 DWORD diffuse;
13782 quad1[] =
13784 {{ 0.0f, 0.0f, 0.0f, 1.0f}, 0xfff9e814},
13785 {{640.0f, 0.0f, 0.0f, 1.0f}, 0xfff9e814},
13786 {{ 0.0f, 480.0f, 1.0f, 1.0f}, 0xfff9e814},
13787 {{640.0f, 480.0f, 1.0f, 1.0f}, 0xfff9e814},
13789 quad2[] =
13791 {{ 0.0f, 0.0f, 0.6f, 1.0f}, 0xff002b7f},
13792 {{640.0f, 0.0f, 0.6f, 1.0f}, 0xff002b7f},
13793 {{ 0.0f, 480.0f, 0.6f, 1.0f}, 0xff002b7f},
13794 {{640.0f, 480.0f, 0.6f, 1.0f}, 0xff002b7f},
13796 quad3[] =
13798 {{ 0.0f, 100.0f, 0.6f, 1.0f}, 0xfff91414},
13799 {{640.0f, 100.0f, 0.6f, 1.0f}, 0xfff91414},
13800 {{ 0.0f, 160.0f, 0.6f, 1.0f}, 0xfff91414},
13801 {{640.0f, 160.0f, 0.6f, 1.0f}, 0xfff91414},
13804 union {
13805 DWORD d;
13806 float f;
13807 } tmpvalue;
13809 IDirect3DSurface9 *offscreen_surface = NULL;
13810 IDirect3DDevice9 *device;
13811 IDirect3D9 *d3d;
13812 D3DCOLOR color;
13813 ULONG refcount;
13814 HWND window;
13815 HRESULT hr;
13817 window = create_window();
13818 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13819 ok(!!d3d, "Failed to create a D3D object.\n");
13820 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
13821 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK)
13823 skip("No NVDB (depth bounds test) support, skipping tests.\n");
13824 goto done;
13826 if (!(device = create_device(d3d, window, window, TRUE)))
13828 skip("Failed to create a D3D device, skipping tests.\n");
13829 goto done;
13832 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
13833 MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
13834 ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
13835 if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
13837 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
13838 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13840 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13841 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13842 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13843 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13844 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13845 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13846 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13847 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13850 hr = IDirect3DDevice9_BeginScene(device);
13851 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13853 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
13854 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13856 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13857 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13859 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
13860 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13862 tmpvalue.f = 0.625;
13863 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
13864 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13866 tmpvalue.f = 0.75;
13867 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
13868 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13870 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13871 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13873 tmpvalue.f = 0.75;
13874 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
13875 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13877 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
13878 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13880 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
13881 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13883 hr = IDirect3DDevice9_EndScene(device);
13884 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13886 color = getPixelColor(device, 150, 130);
13887 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13888 color = getPixelColor(device, 150, 200);
13889 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13890 color = getPixelColor(device, 150, 300-5);
13891 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13892 color = getPixelColor(device, 150, 300+5);
13893 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
13894 color = getPixelColor(device, 150, 330);
13895 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
13896 color = getPixelColor(device, 150, 360-5);
13897 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
13898 color = getPixelColor(device, 150, 360+5);
13899 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13901 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13902 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13903 refcount = IDirect3DDevice9_Release(device);
13904 ok(!refcount, "Device has %u references left.\n", refcount);
13905 done:
13906 IDirect3D9_Release(d3d);
13907 DestroyWindow(window);
13910 static void depth_buffer_test(void)
13912 static const struct
13914 struct vec3 position;
13915 DWORD diffuse;
13917 quad1[] =
13919 {{-1.0, 1.0, 0.33f}, 0xff00ff00},
13920 {{ 1.0, 1.0, 0.33f}, 0xff00ff00},
13921 {{-1.0, -1.0, 0.33f}, 0xff00ff00},
13922 {{ 1.0, -1.0, 0.33f}, 0xff00ff00},
13924 quad2[] =
13926 {{-1.0, 1.0, 0.50f}, 0xffff00ff},
13927 {{ 1.0, 1.0, 0.50f}, 0xffff00ff},
13928 {{-1.0, -1.0, 0.50f}, 0xffff00ff},
13929 {{ 1.0, -1.0, 0.50f}, 0xffff00ff},
13931 quad3[] =
13933 {{-1.0, 1.0, 0.66f}, 0xffff0000},
13934 {{ 1.0, 1.0, 0.66f}, 0xffff0000},
13935 {{-1.0, -1.0, 0.66f}, 0xffff0000},
13936 {{ 1.0, -1.0, 0.66f}, 0xffff0000},
13938 static const DWORD expected_colors[4][4] =
13940 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
13941 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
13942 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
13943 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
13946 IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
13947 IDirect3DDevice9 *device;
13948 unsigned int i, j;
13949 D3DVIEWPORT9 vp;
13950 IDirect3D9 *d3d;
13951 D3DCOLOR color;
13952 ULONG refcount;
13953 HWND window;
13954 HRESULT hr;
13956 window = create_window();
13957 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13958 ok(!!d3d, "Failed to create a D3D object.\n");
13959 if (!(device = create_device(d3d, window, window, TRUE)))
13961 skip("Failed to create a D3D device, skipping tests.\n");
13962 goto done;
13965 vp.X = 0;
13966 vp.Y = 0;
13967 vp.Width = 640;
13968 vp.Height = 480;
13969 vp.MinZ = 0.0;
13970 vp.MaxZ = 1.0;
13972 hr = IDirect3DDevice9_SetViewport(device, &vp);
13973 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
13975 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13976 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13977 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13978 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13979 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13980 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13981 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13982 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13983 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13984 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13986 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
13987 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
13988 hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
13989 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
13990 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13991 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
13992 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
13993 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13994 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13995 D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
13996 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13998 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
13999 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14000 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
14001 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14003 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
14004 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14005 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
14006 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14008 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
14009 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14010 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
14011 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14013 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
14014 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14015 hr = IDirect3DDevice9_BeginScene(device);
14016 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14017 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
14018 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14019 hr = IDirect3DDevice9_EndScene(device);
14020 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14022 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
14023 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14025 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
14026 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14028 hr = IDirect3DDevice9_BeginScene(device);
14029 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14030 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
14031 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14032 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
14033 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14034 hr = IDirect3DDevice9_EndScene(device);
14035 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14037 for (i = 0; i < 4; ++i)
14039 for (j = 0; j < 4; ++j)
14041 unsigned int x = 80 * ((2 * j) + 1);
14042 unsigned int y = 60 * ((2 * i) + 1);
14043 color = getPixelColor(device, x, y);
14044 ok(color_match(color, expected_colors[i][j], 0),
14045 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
14049 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14050 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14052 IDirect3DSurface9_Release(backbuffer);
14053 IDirect3DSurface9_Release(rt3);
14054 IDirect3DSurface9_Release(rt2);
14055 IDirect3DSurface9_Release(rt1);
14056 refcount = IDirect3DDevice9_Release(device);
14057 ok(!refcount, "Device has %u references left.\n", refcount);
14058 done:
14059 IDirect3D9_Release(d3d);
14060 DestroyWindow(window);
14063 /* Test that partial depth copies work the way they're supposed to. The clear
14064 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
14065 * the following draw should only copy back the part that was modified. */
14066 static void depth_buffer2_test(void)
14068 static const struct
14070 struct vec3 position;
14071 DWORD diffuse;
14073 quad[] =
14075 {{-1.0f, 1.0f, 0.66f}, 0xffff0000},
14076 {{ 1.0f, 1.0f, 0.66f}, 0xffff0000},
14077 {{-1.0f, -1.0f, 0.66f}, 0xffff0000},
14078 {{ 1.0f, -1.0f, 0.66f}, 0xffff0000},
14081 IDirect3DSurface9 *backbuffer, *rt1, *rt2;
14082 IDirect3DDevice9 *device;
14083 unsigned int i, j;
14084 D3DVIEWPORT9 vp;
14085 IDirect3D9 *d3d;
14086 D3DCOLOR color;
14087 ULONG refcount;
14088 HWND window;
14089 HRESULT hr;
14091 window = create_window();
14092 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14093 ok(!!d3d, "Failed to create a D3D object.\n");
14094 if (!(device = create_device(d3d, window, window, TRUE)))
14096 skip("Failed to create a D3D device, skipping tests.\n");
14097 goto done;
14100 vp.X = 0;
14101 vp.Y = 0;
14102 vp.Width = 640;
14103 vp.Height = 480;
14104 vp.MinZ = 0.0;
14105 vp.MaxZ = 1.0;
14107 hr = IDirect3DDevice9_SetViewport(device, &vp);
14108 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
14110 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14111 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14112 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14113 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14114 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14115 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14116 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
14117 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14118 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
14119 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14121 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
14122 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
14123 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
14124 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
14125 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
14126 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
14127 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
14128 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14130 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
14131 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14132 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
14133 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14135 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
14136 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14137 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
14138 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14140 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
14141 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14142 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
14143 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14145 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
14146 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14148 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
14149 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14151 hr = IDirect3DDevice9_BeginScene(device);
14152 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14153 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14154 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14155 hr = IDirect3DDevice9_EndScene(device);
14156 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14158 for (i = 0; i < 4; ++i)
14160 for (j = 0; j < 4; ++j)
14162 unsigned int x = 80 * ((2 * j) + 1);
14163 unsigned int y = 60 * ((2 * i) + 1);
14164 color = getPixelColor(device, x, y);
14165 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
14166 "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
14170 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14171 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14173 IDirect3DSurface9_Release(backbuffer);
14174 IDirect3DSurface9_Release(rt2);
14175 IDirect3DSurface9_Release(rt1);
14176 refcount = IDirect3DDevice9_Release(device);
14177 ok(!refcount, "Device has %u references left.\n", refcount);
14178 done:
14179 IDirect3D9_Release(d3d);
14180 DestroyWindow(window);
14183 static void depth_blit_test(void)
14185 static const struct
14187 struct vec3 position;
14188 DWORD diffuse;
14190 quad1[] =
14192 {{-1.0f, 1.0f, 0.33f}, 0xff00ff00},
14193 {{ 1.0f, 1.0f, 0.33f}, 0xff00ff00},
14194 {{-1.0f, -1.0f, 0.33f}, 0xff00ff00},
14195 {{ 1.0f, -1.0f, 0.33f}, 0xff00ff00},
14197 quad2[] =
14199 {{-1.0f, 1.0f, 0.66f}, 0xff0000ff},
14200 {{ 1.0f, 1.0f, 0.66f}, 0xff0000ff},
14201 {{-1.0f, -1.0f, 0.66f}, 0xff0000ff},
14202 {{ 1.0f, -1.0f, 0.66f}, 0xff0000ff},
14204 static const DWORD expected_colors[4][4] =
14206 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
14207 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
14208 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
14209 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
14212 IDirect3DSurface9 *backbuffer, *ds1, *ds2, *ds3;
14213 IDirect3DDevice9 *device;
14214 RECT src_rect, dst_rect;
14215 unsigned int i, j;
14216 D3DVIEWPORT9 vp;
14217 IDirect3D9 *d3d;
14218 D3DCOLOR color;
14219 ULONG refcount;
14220 HWND window;
14221 HRESULT hr;
14223 window = create_window();
14224 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14225 ok(!!d3d, "Failed to create a D3D object.\n");
14226 if (!(device = create_device(d3d, window, window, TRUE)))
14228 skip("Failed to create a D3D device, skipping tests.\n");
14229 goto done;
14232 vp.X = 0;
14233 vp.Y = 0;
14234 vp.Width = 640;
14235 vp.Height = 480;
14236 vp.MinZ = 0.0;
14237 vp.MaxZ = 1.0;
14239 hr = IDirect3DDevice9_SetViewport(device, &vp);
14240 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
14242 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
14243 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14244 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
14245 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
14246 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
14247 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
14248 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
14249 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14250 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 320, 240, D3DFMT_D24S8, 0, 0, FALSE, &ds3, NULL);
14251 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
14253 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14254 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14255 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14256 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14257 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
14258 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14259 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
14260 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14262 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14263 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14264 SetRect(&dst_rect, 0, 0, 480, 360);
14265 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
14266 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14267 SetRect(&dst_rect, 0, 0, 320, 240);
14268 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
14269 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14271 /* Partial blit. */
14272 SetRect(&src_rect, 0, 0, 320, 240);
14273 SetRect(&dst_rect, 0, 0, 320, 240);
14274 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
14275 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14276 /* Flipped. */
14277 SetRect(&src_rect, 0, 0, 640, 480);
14278 SetRect(&dst_rect, 0, 480, 640, 0);
14279 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
14280 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14281 /* Full, explicit. */
14282 SetRect(&src_rect, 0, 0, 640, 480);
14283 SetRect(&dst_rect, 0, 0, 640, 480);
14284 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
14285 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14286 /* Filtered blit. */
14287 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
14288 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14289 /* Depth -> color blit.*/
14290 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
14291 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14292 IDirect3DSurface9_Release(backbuffer);
14293 /* Full surface, different sizes */
14294 hr = IDirect3DDevice9_StretchRect(device, ds3, NULL, ds1, NULL, D3DTEXF_POINT);
14295 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14296 hr = IDirect3DDevice9_StretchRect(device, ds1, NULL, ds3, NULL, D3DTEXF_POINT);
14297 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14299 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
14300 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14301 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
14302 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14303 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
14304 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14306 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
14307 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14308 hr = IDirect3DDevice9_BeginScene(device);
14309 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14310 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
14311 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14312 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
14313 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14314 hr = IDirect3DDevice9_EndScene(device);
14315 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14317 for (i = 0; i < 4; ++i)
14319 for (j = 0; j < 4; ++j)
14321 unsigned int x = 80 * ((2 * j) + 1);
14322 unsigned int y = 60 * ((2 * i) + 1);
14323 color = getPixelColor(device, x, y);
14324 ok(color_match(color, expected_colors[i][j], 0),
14325 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
14329 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14330 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14332 IDirect3DSurface9_Release(ds3);
14333 IDirect3DSurface9_Release(ds2);
14334 IDirect3DSurface9_Release(ds1);
14335 refcount = IDirect3DDevice9_Release(device);
14336 ok(!refcount, "Device has %u references left.\n", refcount);
14337 done:
14338 IDirect3D9_Release(d3d);
14339 DestroyWindow(window);
14342 static void intz_test(void)
14344 static const DWORD ps_code[] =
14346 0xffff0200, /* ps_2_0 */
14347 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
14348 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
14349 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
14350 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
14351 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
14352 0x03010042, 0x800f0001, 0xb0e40000, 0xa0e40800, /* texldp r1, t0, s0 */
14353 0x02000001, 0x80020000, 0x80000001, /* mov r0.y, r1.x */
14354 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14355 0x0000ffff, /* end */
14357 struct
14359 float x, y, z;
14360 float s, t, p, q;
14362 quad[] =
14364 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
14365 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
14366 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
14367 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
14369 half_quad_1[] =
14371 { -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
14372 { 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
14373 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
14374 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
14376 half_quad_2[] =
14378 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
14379 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
14380 { -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
14381 { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
14383 struct
14385 UINT x, y;
14386 D3DCOLOR color;
14388 expected_colors[] =
14390 { 80, 100, 0x20204020},
14391 {240, 100, 0x6060bf60},
14392 {400, 100, 0x9f9f409f},
14393 {560, 100, 0xdfdfbfdf},
14394 { 80, 450, 0x20204020},
14395 {240, 450, 0x6060bf60},
14396 {400, 450, 0x9f9f409f},
14397 {560, 450, 0xdfdfbfdf},
14400 IDirect3DSurface9 *original_rt, *rt;
14401 struct surface_readback rb;
14402 IDirect3DTexture9 *texture;
14403 IDirect3DPixelShader9 *ps;
14404 IDirect3DDevice9 *device;
14405 IDirect3DSurface9 *ds;
14406 IDirect3D9 *d3d;
14407 ULONG refcount;
14408 D3DCAPS9 caps;
14409 HWND window;
14410 HRESULT hr;
14411 UINT i;
14413 window = create_window();
14414 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14415 ok(!!d3d, "Failed to create a D3D object.\n");
14416 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
14417 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
14419 skip("No INTZ support, skipping INTZ test.\n");
14420 goto done;
14422 if (!(device = create_device(d3d, window, window, TRUE)))
14424 skip("Failed to create a D3D device, skipping tests.\n");
14425 goto done;
14428 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14429 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
14430 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
14432 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
14433 IDirect3DDevice9_Release(device);
14434 goto done;
14436 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
14438 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
14439 IDirect3DDevice9_Release(device);
14440 goto done;
14443 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14444 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14446 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
14447 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
14448 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
14449 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
14450 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
14451 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
14452 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
14453 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
14455 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
14456 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14457 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14458 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14459 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
14460 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14461 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14462 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14463 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14464 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14466 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
14467 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14468 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
14469 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14470 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
14471 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14472 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
14473 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14474 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
14475 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14477 /* Render offscreen, using the INTZ texture as depth buffer */
14478 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14479 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14480 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14481 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14482 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14483 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14484 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14485 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14487 /* Setup the depth/stencil surface. */
14488 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14489 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14491 hr = IDirect3DDevice9_BeginScene(device);
14492 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14493 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14494 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14495 hr = IDirect3DDevice9_EndScene(device);
14496 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14498 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14499 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14500 IDirect3DSurface9_Release(ds);
14501 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14502 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14503 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14504 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14505 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14506 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14508 /* Read the depth values back. */
14509 hr = IDirect3DDevice9_BeginScene(device);
14510 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14511 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14512 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14513 hr = IDirect3DDevice9_EndScene(device);
14514 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14516 get_rt_readback(original_rt, &rb);
14517 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14519 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
14520 ok(color_match(color, expected_colors[i].color, 1),
14521 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14522 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14524 release_surface_readback(&rb);
14526 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14527 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14529 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14530 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14531 IDirect3DTexture9_Release(texture);
14533 /* Render onscreen while using the INTZ texture as depth buffer */
14534 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
14535 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
14536 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14537 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14538 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14539 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14540 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14541 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14543 /* Setup the depth/stencil surface. */
14544 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14545 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14547 hr = IDirect3DDevice9_BeginScene(device);
14548 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14549 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14550 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14551 hr = IDirect3DDevice9_EndScene(device);
14552 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14554 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14555 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14556 IDirect3DSurface9_Release(ds);
14557 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14558 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14559 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14560 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14562 /* Read the depth values back. */
14563 hr = IDirect3DDevice9_BeginScene(device);
14564 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14565 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14566 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14567 hr = IDirect3DDevice9_EndScene(device);
14568 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14570 get_rt_readback(original_rt, &rb);
14571 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14573 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
14574 ok(color_match(color, expected_colors[i].color, 1),
14575 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14576 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14578 release_surface_readback(&rb);
14580 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14581 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14583 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14584 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14585 IDirect3DTexture9_Release(texture);
14587 /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
14588 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
14589 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
14590 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14591 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14593 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14594 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14595 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14596 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14597 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14598 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14600 /* Setup the depth/stencil surface. */
14601 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14602 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14604 hr = IDirect3DDevice9_BeginScene(device);
14605 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14606 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
14607 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14608 hr = IDirect3DDevice9_EndScene(device);
14609 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14611 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14612 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14614 hr = IDirect3DDevice9_BeginScene(device);
14615 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14616 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
14617 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14618 hr = IDirect3DDevice9_EndScene(device);
14619 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14621 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14622 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14623 IDirect3DSurface9_Release(ds);
14624 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14625 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14626 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14627 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14629 /* Read the depth values back. */
14630 hr = IDirect3DDevice9_BeginScene(device);
14631 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14632 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14633 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14634 hr = IDirect3DDevice9_EndScene(device);
14635 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14637 get_rt_readback(original_rt, &rb);
14638 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14640 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
14641 ok(color_match(color, expected_colors[i].color, 1),
14642 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14643 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14645 release_surface_readback(&rb);
14647 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14648 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14650 IDirect3DTexture9_Release(texture);
14651 IDirect3DPixelShader9_Release(ps);
14652 IDirect3DSurface9_Release(original_rt);
14653 IDirect3DSurface9_Release(rt);
14654 refcount = IDirect3DDevice9_Release(device);
14655 ok(!refcount, "Device has %u references left.\n", refcount);
14656 done:
14657 IDirect3D9_Release(d3d);
14658 DestroyWindow(window);
14661 static void shadow_test(void)
14663 static const DWORD ps_code[] =
14665 0xffff0200, /* ps_2_0 */
14666 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
14667 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
14668 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
14669 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
14670 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
14671 0x03010042, 0x800f0001, 0xb0e40000, 0xa0e40800, /* texldp r1, t0, s0 */
14672 0x02000001, 0x80020000, 0x80000001, /* mov r0.y, r1.x */
14673 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14674 0x0000ffff, /* end */
14676 struct
14678 D3DFORMAT format;
14679 const char *name;
14681 formats[] =
14683 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
14684 {D3DFMT_D32, "D3DFMT_D32"},
14685 {D3DFMT_D15S1, "D3DFMT_D15S1"},
14686 {D3DFMT_D24S8, "D3DFMT_D24S8"},
14687 {D3DFMT_D24X8, "D3DFMT_D24X8"},
14688 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
14689 {D3DFMT_D16, "D3DFMT_D16"},
14690 {D3DFMT_D32F_LOCKABLE, "D3DFMT_D32F_LOCKABLE"},
14691 {D3DFMT_D24FS8, "D3DFMT_D24FS8"},
14693 struct
14695 float x, y, z;
14696 float s, t, p, q;
14698 quad[] =
14700 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
14701 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
14702 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
14703 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
14705 struct
14707 UINT x, y;
14708 D3DCOLOR color;
14710 expected_colors[] =
14712 {400, 60, 0x00000000},
14713 {560, 180, 0xffff00ff},
14714 {560, 300, 0xffff00ff},
14715 {400, 420, 0xffffffff},
14716 {240, 420, 0xffffffff},
14717 { 80, 300, 0x00000000},
14718 { 80, 180, 0x00000000},
14719 {240, 60, 0x00000000},
14722 IDirect3DSurface9 *original_ds, *original_rt, *rt;
14723 struct surface_readback rb;
14724 IDirect3DPixelShader9 *ps;
14725 IDirect3DDevice9 *device;
14726 IDirect3D9 *d3d;
14727 ULONG refcount;
14728 D3DCAPS9 caps;
14729 HWND window;
14730 HRESULT hr;
14731 UINT i;
14733 window = create_window();
14734 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14735 ok(!!d3d, "Failed to create a D3D object.\n");
14736 if (!(device = create_device(d3d, window, window, TRUE)))
14738 skip("Failed to create a D3D device, skipping tests.\n");
14739 goto done;
14742 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14743 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
14744 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
14746 skip("No pixel shader 2.0 support, skipping shadow test.\n");
14747 IDirect3DDevice9_Release(device);
14748 goto done;
14751 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14752 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14753 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
14754 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
14756 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
14757 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
14758 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
14759 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
14760 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
14762 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
14763 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14764 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14765 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14766 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
14767 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14768 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14769 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14770 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14771 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14773 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
14774 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14775 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
14776 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14777 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
14778 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14779 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
14780 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14781 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
14782 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14784 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
14786 D3DFORMAT format = formats[i].format;
14787 IDirect3DTexture9 *texture;
14788 IDirect3DSurface9 *ds;
14789 unsigned int j;
14791 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
14792 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format)))
14793 continue;
14795 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
14796 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
14797 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
14799 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14800 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14802 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14803 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14805 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14806 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14808 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14809 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14811 /* Setup the depth/stencil surface. */
14812 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14813 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14815 hr = IDirect3DDevice9_BeginScene(device);
14816 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14817 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14818 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14819 hr = IDirect3DDevice9_EndScene(device);
14820 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14822 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14823 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14824 IDirect3DSurface9_Release(ds);
14826 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14827 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14829 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14830 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14832 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14833 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14835 /* Do the actual shadow mapping. */
14836 hr = IDirect3DDevice9_BeginScene(device);
14837 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14838 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14839 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14840 hr = IDirect3DDevice9_EndScene(device);
14841 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14843 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14844 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14845 IDirect3DTexture9_Release(texture);
14847 get_rt_readback(original_rt, &rb);
14848 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
14850 D3DCOLOR color = get_readback_color(&rb, expected_colors[j].x, expected_colors[j].y);
14851 /* Geforce 7 on Windows returns 1.0 in alpha when the depth format is D24S8 or D24X8,
14852 * whereas other GPUs (all AMD, newer Nvidia) return the same value they return in .rgb.
14853 * Accept alpha mismatches as broken but make sure to check the color channels. */
14854 ok(color_match(color, expected_colors[j].color, 0)
14855 || broken(color_match(color & 0x00ffffff, expected_colors[j].color & 0x00ffffff, 0)),
14856 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
14857 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
14858 formats[i].name, color);
14860 release_surface_readback(&rb);
14862 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14863 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14866 IDirect3DPixelShader9_Release(ps);
14867 IDirect3DSurface9_Release(original_ds);
14868 IDirect3DSurface9_Release(original_rt);
14869 IDirect3DSurface9_Release(rt);
14870 refcount = IDirect3DDevice9_Release(device);
14871 ok(!refcount, "Device has %u references left.\n", refcount);
14872 done:
14873 IDirect3D9_Release(d3d);
14874 DestroyWindow(window);
14877 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
14879 static const struct
14881 struct vec3 position;
14882 DWORD diffuse;
14884 quad1[] =
14886 {{-1.0f, -1.0f, 0.0f}, 0xfff9e814},
14887 {{-1.0f, 1.0f, 0.0f}, 0xfff9e814},
14888 {{ 1.0f, -1.0f, 0.0f}, 0xfff9e814},
14889 {{ 1.0f, 1.0f, 0.0f}, 0xfff9e814},
14891 quad2[] =
14893 {{-1.0f, -1.0f, 0.0f}, 0xff002b7f},
14894 {{-1.0f, 1.0f, 0.0f}, 0xff002b7f},
14895 {{ 1.0f, -1.0f, 0.0f}, 0xff002b7f},
14896 {{ 1.0f, 1.0f, 0.0f}, 0xff002b7f},
14898 D3DCOLOR color;
14899 HRESULT hr;
14901 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
14902 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14904 hr = IDirect3DDevice9_BeginScene(device);
14905 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14907 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
14908 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14910 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
14911 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14912 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
14913 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14915 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
14916 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14917 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
14918 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14920 hr = IDirect3DDevice9_EndScene(device);
14921 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14923 color = getPixelColor(device, 1, 240);
14924 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
14925 color = getPixelColor(device, 638, 240);
14926 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
14928 color = getPixelColor(device, 1, 241);
14929 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
14930 color = getPixelColor(device, 638, 241);
14931 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
14934 static void clip_planes_test(void)
14936 IDirect3DSurface9 *offscreen_surface, *original_rt;
14937 IDirect3DTexture9 *offscreen = NULL;
14938 IDirect3DVertexShader9 *shader;
14939 IDirect3DDevice9 *device;
14940 IDirect3D9 *d3d;
14941 ULONG refcount;
14942 D3DCAPS9 caps;
14943 HWND window;
14944 HRESULT hr;
14946 static const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
14947 static const DWORD shader_code[] =
14949 0xfffe0200, /* vs_2_0 */
14950 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
14951 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
14952 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
14953 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
14954 0x0000ffff /* end */
14957 window = create_window();
14958 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14959 ok(!!d3d, "Failed to create a D3D object.\n");
14960 if (!(device = create_device(d3d, window, window, TRUE)))
14962 skip("Failed to create a D3D device, skipping tests.\n");
14963 goto done;
14966 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14967 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
14968 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
14970 skip("No vs_2_0 support, skipping tests.\n");
14971 IDirect3DDevice9_Release(device);
14972 goto done;
14975 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14976 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14978 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14979 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14980 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
14981 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14982 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
14983 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14984 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
14985 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14987 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
14988 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
14989 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14990 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
14992 IDirect3DDevice9_SetClipPlane(device, 0, plane0);
14994 clip_planes(device, "Onscreen FFP");
14996 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
14997 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
14998 hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
14999 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
15000 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
15001 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
15003 clip_planes(device, "Offscreen FFP");
15005 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15006 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
15008 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
15009 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
15010 hr = IDirect3DDevice9_SetVertexShader(device, shader);
15011 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
15013 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15014 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
15016 clip_planes(device, "Onscreen vertex shader");
15018 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
15019 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
15021 clip_planes(device, "Offscreen vertex shader");
15023 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15024 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
15026 IDirect3DVertexShader9_Release(shader);
15027 IDirect3DSurface9_Release(original_rt);
15028 IDirect3DSurface9_Release(offscreen_surface);
15029 IDirect3DTexture9_Release(offscreen);
15030 refcount = IDirect3DDevice9_Release(device);
15031 ok(!refcount, "Device has %u references left.\n", refcount);
15032 done:
15033 IDirect3D9_Release(d3d);
15034 DestroyWindow(window);
15037 static void fp_special_test(void)
15039 /* Microsoft's assembler generates nan and inf with "1.#QNAN" and "1.#INF." respectively */
15040 static const DWORD vs_header[] =
15042 0xfffe0200, /* vs_2_0 */
15043 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
15044 0x05000051, 0xa00f0001, 0x7fc00000, 0xff800000, 0x7f800000, 0x00000000, /* def c1, nan, -inf, inf, 0 */
15045 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
15046 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
15049 static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001}; /* log r0.x, v1.x */
15050 static const DWORD vs_pow[] =
15051 {0x03000020, 0x80010000, 0x90000001, 0x90000001}; /* pow r0.x, v1.x, v1.x */
15052 static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001}; /* nrm r0.xyz, v1.x */
15053 static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001}; /* rcp r0.x, v1.x */
15054 static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001}; /* rcp r0.x, -v1.x */
15055 static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001}; /* rsq r0.x, v1.x */
15056 static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001}; /* rsq r0.x, -v1.x */
15057 static const DWORD vs_lit[] = {0x02000010, 0x800f0000, 0x90000001, /* lit r0, v1.xxxx */
15058 0x02000001, 0x80010000, 0x80aa0000}; /* mov r0.x, v0.z */
15059 static const DWORD vs_def1[] = {0x02000001, 0x80010000, 0xa0000001}; /* mov r0.x, c1.x */
15060 static const DWORD vs_def2[] = {0x02000001, 0x80010000, 0xa0550001}; /* mov r0.x, c1.y */
15061 static const DWORD vs_def3[] = {0x02000001, 0x80010000, 0xa0aa0001}; /* mov r0.x, c1.z */
15063 static const DWORD vs_footer[] =
15065 0x03000005, 0x80020000, 0x80000000, 0xa0ff0000, /* mul r0.y, r0.x, c0.w */
15066 0x0300000d, 0x80040000, 0x80000000, 0x80550000, /* sge r0.z, r0.x, r0.y */
15067 0x0300000d, 0x80020000, 0x80e40000, 0x80000000, /* sge r0.y, r0, r0.x */
15068 0x03000005, 0x80040000, 0x80550000, 0x80e40000, /* mul r0.z, r0.y, r0 */
15069 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
15070 0x0300000c, 0x80020000, 0x80000000, 0x80000000, /* slt r0.y, r0.x, r0.x */
15071 0x03000002, 0x80040000, 0x80550000, 0x80550000, /* add r0.z, r0.y, r0.y */
15072 0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000, /* slt r0.y, c0.x, r0.w */
15073 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
15074 0x03000002, 0x80040000, 0x81550000, 0xa0e40000, /* add r0.z, -r0.y, c0 */
15075 0x0300000c, 0x80080000, 0xa0000000, 0x80e40000, /* slt r0.w, c0.x, r0 */
15076 0x03000005, 0x80040000, 0x80ff0000, 0x80e40000, /* mul r0.z, r0.w, r0 */
15077 0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000, /* mad r0.y, r0.z, c0, r0 */
15078 0x02000001, 0xe0030000, 0x80e40000, /* mov oT0.xy, r0 */
15079 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
15080 0x0000ffff, /* end */
15083 static const struct
15085 const char *name;
15086 const DWORD *ops;
15087 DWORD size;
15088 D3DCOLOR r500;
15089 D3DCOLOR r600;
15090 D3DCOLOR nv40;
15091 D3DCOLOR nv50;
15092 D3DCOLOR warp;
15094 vs_body[] =
15096 /* The basic ideas here are:
15097 * 2.0 * +/-INF == +/-INF
15098 * NAN != NAN
15100 * The vertex shader value is written to the red component, with 0.0
15101 * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
15102 * result in 0x00. The pixel shader value is written to the green
15103 * component, but here 0.0 also results in 0x00. The actual value is
15104 * written to the blue component.
15106 * There are considerable differences between graphics cards in how
15107 * these are handled, but pow and nrm never generate INF or NAN on
15108 * real hardware. */
15109 {"log", vs_log, sizeof(vs_log), 0x00000000, 0x00000000, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
15110 {"pow", vs_pow, sizeof(vs_pow), 0x000000ff, 0x000000ff, 0x0000ff00, 0x000000ff, 0x00008000},
15111 {"nrm", vs_nrm, sizeof(vs_nrm), 0x00ff0000, 0x00ff0000, 0x0000ff00, 0x00ff0000, 0x00008000},
15112 {"rcp1", vs_rcp1, sizeof(vs_rcp1), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
15113 {"rcp2", vs_rcp2, sizeof(vs_rcp2), 0x000000ff, 0x00000000, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
15114 {"rsq1", vs_rsq1, sizeof(vs_rsq1), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
15115 {"rsq2", vs_rsq2, sizeof(vs_rsq2), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
15116 {"lit", vs_lit, sizeof(vs_lit), 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
15117 {"def1", vs_def1, sizeof(vs_def1), 0x000000ff, 0x00007f00, 0x0000ff00, 0x00007f00, 0x00008000},
15118 {"def2", vs_def2, sizeof(vs_def2), 0x00ff0000, 0x00ff7f00, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
15119 {"def3", vs_def3, sizeof(vs_def3), 0x00ff00ff, 0x00ff7f00, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
15122 static const DWORD ps_code[] =
15124 0xffff0200, /* ps_2_0 */
15125 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
15126 0x0200001f, 0x80000000, 0xb0030000, /* dcl t0.xy */
15127 0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000, /* max r1.x, t0, c0 */
15128 0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000, /* min r0.x, t0, c0 */
15129 0x03000002, 0x80010000, 0x80e40000, 0x81e40001, /* add r0.x, r0, -r1 */
15130 0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000, /* mad r1.x, t0, c0.w. -t0 */
15131 0x02000023, 0x80010002, 0x80e40001, /* abs r2.x, r1 */
15132 0x02000023, 0x80010000, 0x80e40000, /* abs r0.x, r0 */
15133 0x02000023, 0x80010001, 0xb0e40000, /* abs r1.x, t0 */
15134 0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r2, c0.z, c0 */
15135 0x02000023, 0x80010002, 0x80e40002, /* abs r2.x, r2 */
15136 0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r1.x, -r1, c0.z, c0 */
15137 0x02000023, 0x80010001, 0x80e40001, /* abs r1.x, r1 */
15138 0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r3.x, -r2, c0.z, c0 */
15139 0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r1, c0.z, c0 */
15140 0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000, /* cmp r0.x, -r0, c0.y, c0 */
15141 0x03000005, 0x80010002, 0x80e40002, 0x80e40003, /* mul r2.x, r2, r3 */
15142 0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000, /* cmp r0.x, -r2, c0.z, r0 */
15143 0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000, /* cmp r0.y, -r1.x, r0.x, c0.x */
15144 0x02000001, 0x80050000, 0xb0c90000, /* mov r0.xz, t0.yzxw */
15145 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.w, c0.z */
15146 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15147 0x0000ffff, /* end */
15150 struct
15152 float x, y, z;
15153 float s;
15155 quad[] =
15157 { -1.0f, 1.0f, 0.0f, 0.0f},
15158 { 1.0f, 1.0f, 1.0f, 0.0f},
15159 { -1.0f, -1.0f, 0.0f, 0.0f},
15160 { 1.0f, -1.0f, 1.0f, 0.0f},
15163 IDirect3DPixelShader9 *ps;
15164 IDirect3DDevice9 *device;
15165 UINT body_size = 0;
15166 IDirect3D9 *d3d;
15167 DWORD *vs_code;
15168 ULONG refcount;
15169 D3DCAPS9 caps;
15170 HWND window;
15171 HRESULT hr;
15172 UINT i;
15174 window = create_window();
15175 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15176 ok(!!d3d, "Failed to create a D3D object.\n");
15177 if (!(device = create_device(d3d, window, window, TRUE)))
15179 skip("Failed to create a D3D device, skipping tests.\n");
15180 goto done;
15183 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15184 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
15185 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
15187 skip("No shader model 2.0 support, skipping floating point specials test.\n");
15188 IDirect3DDevice9_Release(device);
15189 goto done;
15192 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
15193 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15195 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
15196 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
15197 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15198 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
15200 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
15201 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15203 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
15204 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
15206 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
15208 if (vs_body[i].size > body_size) body_size = vs_body[i].size;
15211 vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
15212 memcpy(vs_code, vs_header, sizeof(vs_header));
15214 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
15216 DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
15217 IDirect3DVertexShader9 *vs;
15218 D3DCOLOR color;
15220 memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
15221 offset += vs_body[i].size / sizeof(*vs_body[i].ops);
15222 memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
15224 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
15225 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
15226 hr = IDirect3DDevice9_SetVertexShader(device, vs);
15227 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
15229 hr = IDirect3DDevice9_BeginScene(device);
15230 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15231 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15232 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15233 hr = IDirect3DDevice9_EndScene(device);
15234 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15236 color = getPixelColor(device, 320, 240);
15237 ok(color_match(color, vs_body[i].r500, 1)
15238 || color_match(color, vs_body[i].r600, 1)
15239 || color_match(color, vs_body[i].nv40, 1)
15240 || color_match(color, vs_body[i].nv50, 1)
15241 || broken(color_match(color, vs_body[i].warp, 1)),
15242 "Expected color 0x%08x, 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
15243 vs_body[i].r500, vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
15245 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15246 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
15248 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
15249 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
15250 IDirect3DVertexShader9_Release(vs);
15253 HeapFree(GetProcessHeap(), 0, vs_code);
15255 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
15256 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
15257 IDirect3DPixelShader9_Release(ps);
15258 refcount = IDirect3DDevice9_Release(device);
15259 ok(!refcount, "Device has %u references left.\n", refcount);
15260 done:
15261 IDirect3D9_Release(d3d);
15262 DestroyWindow(window);
15265 static void srgbwrite_format_test(void)
15267 IDirect3D9 *d3d;
15268 IDirect3DSurface9 *rt, *backbuffer;
15269 IDirect3DTexture9 *texture;
15270 IDirect3DDevice9 *device;
15271 ULONG refcount;
15272 HWND window;
15273 HRESULT hr;
15274 int i;
15275 DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
15276 static const struct
15278 D3DFORMAT fmt;
15279 const char *name;
15281 formats[] =
15283 { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
15284 { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
15285 { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
15286 { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
15287 { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
15289 static const struct
15291 float x, y, z;
15292 float u, v;
15294 quad[] =
15296 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
15297 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
15298 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
15299 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
15302 window = create_window();
15303 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15304 ok(!!d3d, "Failed to create a D3D object.\n");
15305 if (!(device = create_device(d3d, window, window, TRUE)))
15307 skip("Failed to create a D3D device, skipping tests.\n");
15308 goto done;
15311 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
15312 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15313 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
15314 ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
15315 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
15316 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
15317 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
15318 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15320 for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
15322 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
15323 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
15325 skip("Format %s not supported as render target, skipping test.\n",
15326 formats[i].name);
15327 continue;
15330 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET,
15331 formats[i].fmt, D3DPOOL_DEFAULT, &texture, NULL);
15332 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
15333 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
15334 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
15336 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
15337 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
15338 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15339 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
15340 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
15341 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
15343 hr = IDirect3DDevice9_BeginScene(device);
15344 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15346 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
15347 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
15348 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
15349 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
15350 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15351 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15353 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
15354 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
15355 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
15356 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15357 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
15358 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
15359 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
15360 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
15361 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15362 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15363 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15364 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
15366 hr = IDirect3DDevice9_EndScene(device);
15367 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15369 IDirect3DSurface9_Release(rt);
15370 IDirect3DTexture9_Release(texture);
15372 color = getPixelColor(device, 360, 240);
15373 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
15374 D3DUSAGE_QUERY_SRGBWRITE,
15375 D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
15377 /* Big slop for R5G6B5 */
15378 ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
15379 formats[i].name, color_srgb, color);
15381 else
15383 /* Big slop for R5G6B5 */
15384 ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
15385 formats[i].name, color_rgb, color);
15388 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15389 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
15392 IDirect3DSurface9_Release(backbuffer);
15393 refcount = IDirect3DDevice9_Release(device);
15394 ok(!refcount, "Device has %u references left.\n", refcount);
15395 done:
15396 IDirect3D9_Release(d3d);
15397 DestroyWindow(window);
15400 static void ds_size_test(void)
15402 IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
15403 IDirect3DDevice9 *device;
15404 DWORD num_passes;
15405 IDirect3D9 *d3d;
15406 ULONG refcount;
15407 HWND window;
15408 HRESULT hr;
15410 static const struct
15412 float x, y, z;
15414 quad[] =
15416 {-1.0f, -1.0f, 0.0f},
15417 {-1.0f, 1.0f, 0.0f},
15418 { 1.0f, -1.0f, 0.0f},
15419 { 1.0f, 1.0f, 0.0f},
15422 window = create_window();
15423 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15424 ok(!!d3d, "Failed to create a D3D object.\n");
15425 if (!(device = create_device(d3d, window, window, TRUE)))
15427 skip("Failed to create a D3D device, skipping tests.\n");
15428 goto done;
15431 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
15432 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
15433 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
15434 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#x.\n", hr);
15435 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
15436 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
15438 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
15439 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
15441 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
15442 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15443 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
15444 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15445 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
15446 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15447 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15448 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
15449 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
15450 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
15451 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
15452 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#x.\n", hr);
15453 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15454 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
15455 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15456 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
15457 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15458 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
15460 /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
15461 * but does not change the surface's contents. */
15462 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
15463 ok(SUCCEEDED(hr), "Target clear failed, hr %#x.\n", hr);
15464 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
15465 ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#x.\n", hr);
15466 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
15467 ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#x.\n", hr);
15469 /* Nvidia does not clear the surface(The color is still 0x000000ff), AMD does(the color is 0x00ff0000) */
15471 /* Turning on any depth-related state results in a ValidateDevice failure */
15472 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15473 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15474 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15475 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
15476 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
15477 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
15478 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15479 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15480 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15481 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15482 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
15483 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
15485 /* Try to draw with the device in an invalid state. */
15486 hr = IDirect3DDevice9_BeginScene(device);
15487 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15488 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15489 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15490 hr = IDirect3DDevice9_EndScene(device);
15491 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15493 /* Don't check the resulting draw unless we find an app that needs it. On
15494 * NVIDIA ValidateDevice() returns CONFLICTINGRENDERSTATE, so the result
15495 * is undefined. On AMD D3D seems to assume the stored Z buffer value is
15496 * 0.0 for all pixels, even those that are covered by the depth buffer. */
15498 hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
15499 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
15500 hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
15501 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
15502 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15503 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
15505 IDirect3DSurface9_Release(readback);
15506 IDirect3DSurface9_Release(ds);
15507 IDirect3DSurface9_Release(rt);
15508 IDirect3DSurface9_Release(old_rt);
15509 IDirect3DSurface9_Release(old_ds);
15510 refcount = IDirect3DDevice9_Release(device);
15511 ok(!refcount, "Device has %u references left.\n", refcount);
15512 done:
15513 IDirect3D9_Release(d3d);
15514 DestroyWindow(window);
15517 static void unbound_sampler_test(void)
15519 IDirect3DPixelShader9 *ps, *ps_cube, *ps_volume;
15520 IDirect3DSurface9 *rt, *old_rt;
15521 IDirect3DDevice9 *device;
15522 IDirect3D9 *d3d;
15523 ULONG refcount;
15524 D3DCAPS9 caps;
15525 DWORD color;
15526 HWND window;
15527 HRESULT hr;
15529 static const DWORD ps_code[] =
15531 0xffff0200, /* ps_2_0 */
15532 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
15533 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
15534 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
15535 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15536 0x0000ffff, /* end */
15538 static const DWORD ps_code_cube[] =
15540 0xffff0200, /* ps_2_0 */
15541 0x0200001f, 0x98000000, 0xa00f0800, /* dcl_cube s0 */
15542 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
15543 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
15544 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15545 0x0000ffff, /* end */
15547 static const DWORD ps_code_volume[] =
15549 0xffff0200, /* ps_2_0 */
15550 0x0200001f, 0xa0000000, 0xa00f0800, /* dcl_volume s0 */
15551 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
15552 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
15553 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15554 0x0000ffff, /* end */
15557 static const struct
15559 float x, y, z;
15560 float u, v;
15562 quad[] =
15564 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
15565 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
15566 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
15567 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
15570 window = create_window();
15571 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15572 ok(!!d3d, "Failed to create a D3D object.\n");
15573 if (!(device = create_device(d3d, window, window, TRUE)))
15575 skip("Failed to create a D3D device, skipping tests.\n");
15576 goto done;
15579 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15580 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
15581 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
15583 skip("No ps_2_0 support, skipping tests.\n");
15584 IDirect3DDevice9_Release(device);
15585 goto done;
15587 if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP) || !(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
15589 skip("No cube / volume texture support, skipping tests.\n");
15590 IDirect3DDevice9_Release(device);
15591 goto done;
15594 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15595 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStage failed, %#x.\n", hr);
15597 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
15598 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
15599 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_cube, &ps_cube);
15600 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
15601 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_volume, &ps_volume);
15602 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
15604 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
15605 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
15607 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
15608 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
15610 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15611 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
15613 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 );
15614 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
15616 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x56ffffff, 1.0f, 0);
15617 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
15619 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15620 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
15622 hr = IDirect3DDevice9_BeginScene(device);
15623 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15624 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15625 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15626 hr = IDirect3DDevice9_EndScene(device);
15627 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15629 color = getPixelColorFromSurface(rt, 32, 32);
15630 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
15632 /* Now try with a cube texture */
15633 hr = IDirect3DDevice9_SetPixelShader(device, ps_cube);
15634 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
15636 hr = IDirect3DDevice9_BeginScene(device);
15637 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15638 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15639 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15640 hr = IDirect3DDevice9_EndScene(device);
15641 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15643 color = getPixelColorFromSurface(rt, 32, 32);
15644 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
15646 /* And then with a volume texture */
15647 hr = IDirect3DDevice9_SetPixelShader(device, ps_volume);
15648 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
15650 hr = IDirect3DDevice9_BeginScene(device);
15651 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15652 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15653 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15654 hr = IDirect3DDevice9_EndScene(device);
15655 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15657 color = getPixelColorFromSurface(rt, 32, 32);
15658 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
15660 IDirect3DSurface9_Release(rt);
15661 IDirect3DSurface9_Release(old_rt);
15662 IDirect3DPixelShader9_Release(ps);
15663 IDirect3DPixelShader9_Release(ps_cube);
15664 IDirect3DPixelShader9_Release(ps_volume);
15665 refcount = IDirect3DDevice9_Release(device);
15666 ok(!refcount, "Device has %u references left.\n", refcount);
15667 done:
15668 IDirect3D9_Release(d3d);
15669 DestroyWindow(window);
15672 static void update_surface_test(void)
15674 static const BYTE blocks[][8] =
15676 {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, /* White */
15677 {0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Red */
15678 {0xe0, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00}, /* Yellow */
15679 {0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Green */
15680 {0xff, 0x07, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Cyan */
15681 {0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Blue */
15682 {0x1f, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Magenta */
15684 static const struct
15686 UINT x, y;
15687 D3DCOLOR color;
15689 expected_colors[] =
15691 { 18, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0xff)},
15692 { 57, 240, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff)},
15693 {109, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0xff)},
15694 {184, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
15695 {290, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
15696 {440, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
15697 {584, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
15699 static const struct
15701 float x, y, z, w;
15702 float u, v;
15704 tri[] =
15706 { 0.0f, 480.0f, 0.0f, 1.0f, 0.0f, 0.0f},
15707 { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
15708 {640.0f, 240.0f, 0.0f, 10.0f, 100.0f, 0.5f},
15710 static const RECT rect_2x2 = {0, 0, 2, 2};
15711 static const struct
15713 UINT src_level;
15714 UINT dst_level;
15715 const RECT *r;
15716 HRESULT hr;
15718 block_size_tests[] =
15720 {1, 0, NULL, D3D_OK},
15721 {0, 1, NULL, D3DERR_INVALIDCALL},
15722 {5, 4, NULL, D3DERR_INVALIDCALL},
15723 {4, 5, NULL, D3DERR_INVALIDCALL},
15724 {4, 5, &rect_2x2, D3DERR_INVALIDCALL},
15725 {5, 5, &rect_2x2, D3D_OK},
15728 IDirect3DSurface9 *src_surface, *dst_surface;
15729 IDirect3DTexture9 *src_tex, *dst_tex;
15730 IDirect3DDevice9 *device;
15731 IDirect3D9 *d3d;
15732 ULONG refcount;
15733 UINT count, i;
15734 HWND window;
15735 HRESULT hr;
15737 window = create_window();
15738 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15739 ok(!!d3d, "Failed to create a D3D object.\n");
15740 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15741 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1)))
15743 skip("DXT1 not supported, skipping tests.\n");
15744 goto done;
15746 if (!(device = create_device(d3d, window, window, TRUE)))
15748 skip("Failed to create a D3D device, skipping tests.\n");
15749 goto done;
15752 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &src_tex, NULL);
15753 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
15754 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &dst_tex, NULL);
15755 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
15757 count = IDirect3DTexture9_GetLevelCount(src_tex);
15758 ok(count == 7, "Got level count %u, expected 7.\n", count);
15760 for (i = 0; i < count; ++i)
15762 UINT row_count, block_count, x, y;
15763 D3DSURFACE_DESC desc;
15764 BYTE *row, *block;
15765 D3DLOCKED_RECT r;
15767 hr = IDirect3DTexture9_GetLevelDesc(src_tex, i, &desc);
15768 ok(SUCCEEDED(hr), "Failed to get level desc, hr %#x.\n", hr);
15770 hr = IDirect3DTexture9_LockRect(src_tex, i, &r, NULL, 0);
15771 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
15773 row_count = ((desc.Height + 3) & ~3) / 4;
15774 block_count = ((desc.Width + 3) & ~3) / 4;
15775 row = r.pBits;
15777 for (y = 0; y < row_count; ++y)
15779 block = row;
15780 for (x = 0; x < block_count; ++x)
15782 memcpy(block, blocks[i], sizeof(blocks[i]));
15783 block += sizeof(blocks[i]);
15785 row += r.Pitch;
15788 hr = IDirect3DTexture9_UnlockRect(src_tex, i);
15789 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
15792 for (i = 0; i < sizeof(block_size_tests) / sizeof(*block_size_tests); ++i)
15794 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, block_size_tests[i].src_level, &src_surface);
15795 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15796 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, block_size_tests[i].dst_level, &dst_surface);
15797 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15799 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, block_size_tests[i].r, dst_surface, NULL);
15800 ok(hr == block_size_tests[i].hr, "Update surface returned %#x for test %u, expected %#x.\n",
15801 hr, i, block_size_tests[i].hr);
15803 IDirect3DSurface9_Release(dst_surface);
15804 IDirect3DSurface9_Release(src_surface);
15807 for (i = 0; i < count; ++i)
15809 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, i, &src_surface);
15810 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15811 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, i, &dst_surface);
15812 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15814 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, NULL, dst_surface, NULL);
15815 ok(SUCCEEDED(hr), "Failed to update surface at level %u, hr %#x.\n", i, hr);
15817 IDirect3DSurface9_Release(dst_surface);
15818 IDirect3DSurface9_Release(src_surface);
15821 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15822 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15823 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
15824 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15825 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
15826 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15827 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)dst_tex);
15828 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
15829 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
15830 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
15831 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
15832 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
15834 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
15835 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
15837 hr = IDirect3DDevice9_BeginScene(device);
15838 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15839 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 1, tri, sizeof(*tri));
15840 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15841 hr = IDirect3DDevice9_EndScene(device);
15842 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15844 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15846 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
15847 ok(color_match(color, expected_colors[i].color, 0),
15848 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15849 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15852 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15853 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
15855 IDirect3DTexture9_Release(dst_tex);
15856 IDirect3DTexture9_Release(src_tex);
15857 refcount = IDirect3DDevice9_Release(device);
15858 ok(!refcount, "Device has %u references left.\n", refcount);
15859 done:
15860 IDirect3D9_Release(d3d);
15861 DestroyWindow(window);
15864 static void multisample_get_rtdata_test(void)
15866 IDirect3DSurface9 *original_ds, *original_rt, *rt, *readback;
15867 IDirect3DDevice9 *device;
15868 IDirect3D9 *d3d;
15869 ULONG refcount;
15870 HWND window;
15871 HRESULT hr;
15873 window = create_window();
15874 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15875 ok(!!d3d, "Failed to create a D3D object.\n");
15876 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15877 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15879 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping tests.\n");
15880 goto done;
15882 if (!(device = create_device(d3d, window, window, TRUE)))
15884 skip("Failed to create a D3D device, skipping tests.\n");
15885 goto done;
15888 hr = IDirect3DDevice9_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
15889 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
15890 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
15891 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_A8R8G8B8,
15892 D3DPOOL_SYSTEMMEM, &readback, NULL);
15893 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
15895 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
15896 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
15897 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
15898 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
15900 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15901 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15902 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15903 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15905 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
15906 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15907 hr = IDirect3DDevice9_GetRenderTargetData(device, rt, readback);
15908 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
15910 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
15911 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15912 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15913 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
15915 IDirect3DSurface9_Release(original_ds);
15916 IDirect3DSurface9_Release(original_rt);
15917 IDirect3DSurface9_Release(readback);
15918 IDirect3DSurface9_Release(rt);
15919 refcount = IDirect3DDevice9_Release(device);
15920 ok(!refcount, "Device has %u references left.\n", refcount);
15921 done:
15922 IDirect3D9_Release(d3d);
15923 DestroyWindow(window);
15926 static void multisampled_depth_buffer_test(void)
15928 IDirect3DDevice9 *device = 0;
15929 IDirect3DSurface9 *original_rt, *rt, *readback, *ds, *original_ds;
15930 IDirect3D9 *d3d;
15931 D3DCAPS9 caps;
15932 HRESULT hr;
15933 D3DPRESENT_PARAMETERS present_parameters;
15934 unsigned int i;
15935 static const struct
15937 float x, y, z;
15938 D3DCOLOR color;
15940 quad_1[] =
15942 { -1.0f, 1.0f, 0.0f, 0xffff0000},
15943 { 1.0f, 1.0f, 1.0f, 0xffff0000},
15944 { -1.0f, -1.0f, 0.0f, 0xffff0000},
15945 { 1.0f, -1.0f, 1.0f, 0xffff0000},
15947 quad_2[] =
15949 { -1.0f, 1.0f, 1.0f, 0xff0000ff},
15950 { 1.0f, 1.0f, 0.0f, 0xff0000ff},
15951 { -1.0f, -1.0f, 1.0f, 0xff0000ff},
15952 { 1.0f, -1.0f, 0.0f, 0xff0000ff},
15954 static const struct
15956 UINT x, y;
15957 D3DCOLOR color;
15959 expected_colors[] =
15961 { 80, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15962 {240, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15963 {400, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15964 {560, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15965 { 80, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15966 {240, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15967 {400, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15968 {560, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15971 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15972 ok(!!d3d, "Failed to create a D3D object.\n");
15974 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
15975 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15977 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled depth buffer test.\n");
15978 IDirect3D9_Release(d3d);
15979 return;
15981 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
15982 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15984 skip("Multisampling not supported for D3DFMT_D24S8, skipping multisampled depth buffer test.\n");
15985 IDirect3D9_Release(d3d);
15986 return;
15989 ZeroMemory(&present_parameters, sizeof(present_parameters));
15990 present_parameters.Windowed = TRUE;
15991 present_parameters.hDeviceWindow = create_window();
15992 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
15993 present_parameters.BackBufferWidth = 640;
15994 present_parameters.BackBufferHeight = 480;
15995 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
15996 present_parameters.EnableAutoDepthStencil = TRUE;
15997 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
15998 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
16000 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16001 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
16002 &present_parameters, &device);
16003 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
16005 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16006 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
16007 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
16009 skip("No unconditional NP2 texture support, skipping multisampled depth buffer test.\n");
16010 goto cleanup;
16013 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
16014 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
16015 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
16016 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
16017 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
16018 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
16020 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
16021 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
16022 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
16023 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
16025 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16026 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16027 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
16028 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16029 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16030 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16031 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
16032 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16033 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
16034 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
16036 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
16037 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16039 /* Render onscreen and then offscreen */
16040 hr = IDirect3DDevice9_BeginScene(device);
16041 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16042 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
16043 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16044 hr = IDirect3DDevice9_EndScene(device);
16045 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16047 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, rt, NULL, D3DTEXF_POINT);
16048 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
16049 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
16050 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16052 hr = IDirect3DDevice9_BeginScene(device);
16053 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16054 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
16055 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16056 hr = IDirect3DDevice9_EndScene(device);
16057 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16059 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, readback, NULL, D3DTEXF_POINT);
16060 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
16062 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16064 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
16065 ok(color_match(color, expected_colors[i].color, 1),
16066 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16067 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16070 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
16071 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
16072 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16073 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16075 /* Render offscreen and then onscreen */
16076 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16077 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16078 IDirect3DSurface9_Release(ds);
16079 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
16080 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
16081 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#x.\n", hr);
16082 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16083 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16085 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
16086 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16088 hr = IDirect3DDevice9_BeginScene(device);
16089 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16090 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
16091 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16092 hr = IDirect3DDevice9_EndScene(device);
16093 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16095 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
16096 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
16097 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16098 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16100 hr = IDirect3DDevice9_BeginScene(device);
16101 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16102 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
16103 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16104 hr = IDirect3DDevice9_EndScene(device);
16105 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16107 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
16108 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
16110 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16112 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
16113 ok(color_match(color, expected_colors[i].color, 1),
16114 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16115 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16118 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16119 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16121 IDirect3DSurface9_Release(ds);
16122 IDirect3DSurface9_Release(readback);
16123 IDirect3DSurface9_Release(rt);
16124 IDirect3DSurface9_Release(original_rt);
16125 cleanup_device(device);
16127 ZeroMemory(&present_parameters, sizeof(present_parameters));
16128 present_parameters.Windowed = TRUE;
16129 present_parameters.hDeviceWindow = create_window();
16130 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
16131 present_parameters.BackBufferWidth = 640;
16132 present_parameters.BackBufferHeight = 480;
16133 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
16134 present_parameters.EnableAutoDepthStencil = TRUE;
16135 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
16136 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
16138 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16139 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
16140 &present_parameters, &device);
16141 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
16143 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
16144 ok(SUCCEEDED(hr), "Failed to clear depth buffer, hr %#x.\n", hr);
16146 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
16147 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
16148 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
16149 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
16150 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
16151 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
16152 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
16153 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
16154 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
16156 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
16157 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
16158 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
16159 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
16160 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
16161 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16162 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16163 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16165 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16166 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16167 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
16168 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16169 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16170 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16171 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
16172 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16173 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
16174 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
16176 /* Render to a multisampled offscreen frame buffer and then blit to
16177 * the onscreen (not multisampled) frame buffer. */
16178 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
16179 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16181 hr = IDirect3DDevice9_BeginScene(device);
16182 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16183 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
16184 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16185 hr = IDirect3DDevice9_EndScene(device);
16186 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16188 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
16189 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
16190 hr = IDirect3DDevice9_StretchRect(device, ds, NULL, original_ds, NULL, D3DTEXF_POINT);
16191 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
16193 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16194 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16195 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
16196 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16198 hr = IDirect3DDevice9_BeginScene(device);
16199 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16200 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
16201 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16202 hr = IDirect3DDevice9_EndScene(device);
16203 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16205 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
16206 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
16208 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16210 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
16211 ok(color_match(color, expected_colors[i].color, 1),
16212 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16213 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16216 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16217 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16219 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16220 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16221 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16222 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
16224 IDirect3DSurface9_Release(original_ds);
16225 IDirect3DSurface9_Release(original_rt);
16226 IDirect3DSurface9_Release(ds);
16227 IDirect3DSurface9_Release(readback);
16228 IDirect3DSurface9_Release(rt);
16229 cleanup:
16230 cleanup_device(device);
16231 IDirect3D9_Release(d3d);
16234 static void resz_test(void)
16236 IDirect3DDevice9 *device = 0;
16237 IDirect3DSurface9 *rt, *original_rt, *ds, *readback, *intz_ds;
16238 D3DCAPS9 caps;
16239 HRESULT hr;
16240 D3DPRESENT_PARAMETERS present_parameters;
16241 unsigned int i;
16242 static const DWORD ps_code[] =
16244 0xffff0200, /* ps_2_0 */
16245 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
16246 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
16247 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
16248 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
16249 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
16250 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
16251 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
16252 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
16253 0x02000001, 0x800f0800, 0x80e40001, /* mov oC0, r1 */
16254 0x0000ffff, /* end */
16256 static const struct
16258 float x, y, z;
16259 float s, t, p, q;
16261 quad[] =
16263 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
16264 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
16265 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
16266 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
16268 static const struct
16270 UINT x, y;
16271 D3DCOLOR color;
16273 expected_colors[] =
16275 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
16276 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
16277 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
16278 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
16279 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
16280 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
16281 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
16282 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
16284 IDirect3DTexture9 *texture;
16285 IDirect3DPixelShader9 *ps;
16286 IDirect3D9 *d3d;
16287 DWORD value;
16289 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16290 ok(!!d3d, "Failed to create a D3D object.\n");
16292 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
16293 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
16295 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
16296 IDirect3D9_Release(d3d);
16297 return;
16299 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
16300 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
16302 skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
16303 IDirect3D9_Release(d3d);
16304 return;
16307 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
16308 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
16310 skip("No INTZ support, skipping RESZ test.\n");
16311 IDirect3D9_Release(d3d);
16312 return;
16315 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
16316 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'))))
16318 skip("No RESZ support, skipping RESZ test.\n");
16319 IDirect3D9_Release(d3d);
16320 return;
16323 ZeroMemory(&present_parameters, sizeof(present_parameters));
16324 present_parameters.Windowed = TRUE;
16325 present_parameters.hDeviceWindow = create_window();
16326 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
16327 present_parameters.BackBufferWidth = 640;
16328 present_parameters.BackBufferHeight = 480;
16329 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
16330 present_parameters.EnableAutoDepthStencil = FALSE;
16331 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
16332 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
16334 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16335 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
16336 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
16338 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16339 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
16340 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
16342 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
16343 cleanup_device(device);
16344 IDirect3D9_Release(d3d);
16345 return;
16347 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
16349 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
16350 cleanup_device(device);
16351 IDirect3D9_Release(d3d);
16352 return;
16355 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
16356 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
16358 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
16359 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
16360 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
16361 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
16362 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
16363 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#x.\n", hr);
16364 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
16365 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
16366 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
16368 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
16369 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
16370 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
16371 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
16372 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
16373 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
16374 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16375 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
16376 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
16377 IDirect3DSurface9_Release(intz_ds);
16378 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
16379 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
16381 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
16382 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
16383 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
16384 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16385 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
16386 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16387 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16388 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16389 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16390 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16392 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
16393 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16394 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
16395 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16396 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
16397 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16398 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
16399 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16400 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
16401 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16403 /* Render offscreen (multisampled), blit the depth buffer
16404 * into the INTZ texture and then check its contents */
16405 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
16406 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16407 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16408 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16409 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
16410 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16412 hr = IDirect3DDevice9_BeginScene(device);
16413 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16414 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16415 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16417 /* The destination depth texture has to be bound to sampler 0 */
16418 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16419 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16421 /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
16422 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
16423 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16424 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
16425 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16426 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
16427 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16428 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16429 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16430 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
16431 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16432 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16433 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16434 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
16435 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16437 /* The actual multisampled depth buffer resolve happens here */
16438 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16439 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16440 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
16441 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
16443 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16444 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16445 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16446 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16447 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16448 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16450 /* Read the depth values back */
16451 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16452 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16453 hr = IDirect3DDevice9_EndScene(device);
16454 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16456 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16458 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
16459 ok(color_match(color, expected_colors[i].color, 1),
16460 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16461 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16464 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16465 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16467 IDirect3DSurface9_Release(ds);
16468 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16469 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16470 IDirect3DTexture9_Release(texture);
16471 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16472 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16473 IDirect3DPixelShader9_Release(ps);
16474 IDirect3DSurface9_Release(readback);
16475 IDirect3DSurface9_Release(original_rt);
16476 IDirect3DSurface9_Release(rt);
16477 cleanup_device(device);
16479 ZeroMemory(&present_parameters, sizeof(present_parameters));
16480 present_parameters.Windowed = TRUE;
16481 present_parameters.hDeviceWindow = create_window();
16482 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
16483 present_parameters.BackBufferWidth = 640;
16484 present_parameters.BackBufferHeight = 480;
16485 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
16486 present_parameters.EnableAutoDepthStencil = TRUE;
16487 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
16488 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
16490 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16491 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
16492 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
16494 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
16495 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
16496 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
16497 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
16498 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
16499 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
16500 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
16501 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
16502 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
16503 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
16504 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
16505 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
16506 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
16507 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16508 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
16509 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16510 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
16511 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
16512 IDirect3DSurface9_Release(intz_ds);
16513 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
16514 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
16516 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
16517 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
16518 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
16519 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16520 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
16521 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16522 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16523 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16524 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16525 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16527 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
16528 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16529 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
16530 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16531 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
16532 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16533 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
16534 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16535 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
16536 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16538 /* Render onscreen, blit the depth buffer into the INTZ texture
16539 * and then check its contents */
16540 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16541 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16542 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16543 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16544 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
16545 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16547 hr = IDirect3DDevice9_BeginScene(device);
16548 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16549 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16550 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16551 hr = IDirect3DDevice9_EndScene(device);
16552 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16554 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16555 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16557 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
16558 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16559 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
16560 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16561 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
16562 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16563 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16564 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16565 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
16566 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16567 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16568 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16569 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
16570 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16572 /* The actual multisampled depth buffer resolve happens here */
16573 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16574 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16575 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
16576 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
16578 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
16579 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16580 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16581 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16582 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16583 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16585 /* Read the depth values back */
16586 hr = IDirect3DDevice9_BeginScene(device);
16587 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16588 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16589 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16590 hr = IDirect3DDevice9_EndScene(device);
16591 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16593 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16595 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
16596 ok(color_match(color, expected_colors[i].color, 1),
16597 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16598 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16601 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16602 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16605 /* Test edge cases - try with no texture at all */
16606 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16607 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16608 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16609 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16610 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16611 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16612 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16613 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16615 hr = IDirect3DDevice9_BeginScene(device);
16616 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16617 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16618 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16619 hr = IDirect3DDevice9_EndScene(device);
16620 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16622 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16623 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16625 /* With a non-multisampled depth buffer */
16626 IDirect3DSurface9_Release(ds);
16627 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
16628 D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
16629 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
16631 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
16632 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16633 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16634 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16635 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16636 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16638 hr = IDirect3DDevice9_BeginScene(device);
16639 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16640 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16641 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16643 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16644 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16646 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
16647 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16648 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
16649 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16650 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
16651 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16652 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16653 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16654 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
16655 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16656 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16657 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16658 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
16659 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16660 hr = IDirect3DDevice9_EndScene(device);
16661 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16663 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16664 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16666 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16667 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16669 /* Read the depth values back. */
16670 hr = IDirect3DDevice9_BeginScene(device);
16671 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16672 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16673 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16674 hr = IDirect3DDevice9_EndScene(device);
16675 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16677 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16679 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
16680 ok(color_match(color, expected_colors[i].color, 1),
16681 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16682 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16685 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16686 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16688 /* Without a current depth-stencil buffer set */
16689 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16690 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16691 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16692 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16694 hr = IDirect3DDevice9_BeginScene(device);
16695 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16696 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16697 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16698 hr = IDirect3DDevice9_EndScene(device);
16699 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16701 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16702 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16704 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16705 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16706 IDirect3DSurface9_Release(ds);
16707 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16708 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16709 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16710 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16711 IDirect3DTexture9_Release(texture);
16712 IDirect3DPixelShader9_Release(ps);
16713 IDirect3DSurface9_Release(readback);
16714 IDirect3DSurface9_Release(original_rt);
16715 cleanup_device(device);
16716 IDirect3D9_Release(d3d);
16719 static void zenable_test(void)
16721 static const struct
16723 struct vec4 position;
16724 D3DCOLOR diffuse;
16726 tquad[] =
16728 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
16729 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xff00ff00},
16730 {{640.0f, 480.0f, 1.5f, 1.0f}, 0xff00ff00},
16731 {{640.0f, 0.0f, 1.5f, 1.0f}, 0xff00ff00},
16733 IDirect3DDevice9 *device;
16734 IDirect3D9 *d3d;
16735 D3DCOLOR color;
16736 ULONG refcount;
16737 D3DCAPS9 caps;
16738 HWND window;
16739 HRESULT hr;
16740 UINT x, y;
16741 UINT i, j;
16742 UINT test;
16743 IDirect3DSurface9 *ds;
16745 window = create_window();
16746 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16747 ok(!!d3d, "Failed to create a D3D object.\n");
16748 if (!(device = create_device(d3d, window, window, TRUE)))
16750 skip("Failed to create a D3D device, skipping tests.\n");
16751 goto done;
16754 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
16755 ok(SUCCEEDED(hr), "Failed to get depth stencil surface, hr %#x.\n", hr);
16757 for (test = 0; test < 2; ++test)
16759 /* The Windows 8 testbot (WARP) appears to clip with
16760 * ZENABLE = D3DZB_TRUE and no depth buffer set. */
16761 static const D3DCOLOR expected_broken[] =
16763 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16764 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16765 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16766 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16769 if (!test)
16771 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16772 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
16774 else
16776 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
16777 ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
16778 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16779 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
16780 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.0f, 0);
16781 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16783 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
16784 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16786 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
16787 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16788 hr = IDirect3DDevice9_BeginScene(device);
16789 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16790 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
16791 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16792 hr = IDirect3DDevice9_EndScene(device);
16793 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16795 for (i = 0; i < 4; ++i)
16797 for (j = 0; j < 4; ++j)
16799 x = 80 * ((2 * j) + 1);
16800 y = 60 * ((2 * i) + 1);
16801 color = getPixelColor(device, x, y);
16802 ok(color_match(color, 0x0000ff00, 1)
16803 || broken(color_match(color, expected_broken[i * 4 + j], 1) && !test),
16804 "Expected color 0x0000ff00 at %u, %u, got 0x%08x, test %u.\n",
16805 x, y, color, test);
16809 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16810 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
16813 IDirect3DSurface9_Release(ds);
16815 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16816 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
16818 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
16819 && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
16821 static const DWORD vs_code[] =
16823 0xfffe0101, /* vs_1_1 */
16824 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
16825 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
16826 0x00000001, 0xd00f0000, 0x90e40000, /* mov oD0, v0 */
16827 0x0000ffff
16829 static const DWORD ps_code[] =
16831 0xffff0101, /* ps_1_1 */
16832 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
16833 0x0000ffff /* end */
16835 static const struct vec3 quad[] =
16837 {-1.0f, -1.0f, -0.5f},
16838 {-1.0f, 1.0f, -0.5f},
16839 { 1.0f, -1.0f, 1.5f},
16840 { 1.0f, 1.0f, 1.5f},
16842 static const D3DCOLOR expected[] =
16844 0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
16845 0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
16846 0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
16847 0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
16849 /* The Windows 8 testbot (WARP) appears to not clip z for regular
16850 * vertices either. */
16851 static const D3DCOLOR expected_broken[] =
16853 0x0020df20, 0x0060df60, 0x009fdf9f, 0x00dfdfdf,
16854 0x00209f20, 0x00609f60, 0x009f9f9f, 0x00df9fdf,
16855 0x00206020, 0x00606060, 0x009f609f, 0x00df60df,
16856 0x00202020, 0x00602060, 0x009f209f, 0x00df20df,
16859 IDirect3DVertexShader9 *vs;
16860 IDirect3DPixelShader9 *ps;
16862 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
16863 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16864 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
16865 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
16866 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
16867 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
16868 hr = IDirect3DDevice9_SetVertexShader(device, vs);
16869 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
16870 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16871 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
16873 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
16874 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16875 hr = IDirect3DDevice9_BeginScene(device);
16876 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16877 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16878 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16879 hr = IDirect3DDevice9_EndScene(device);
16880 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16882 for (i = 0; i < 4; ++i)
16884 for (j = 0; j < 4; ++j)
16886 x = 80 * ((2 * j) + 1);
16887 y = 60 * ((2 * i) + 1);
16888 color = getPixelColor(device, x, y);
16889 ok(color_match(color, expected[i * 4 + j], 1)
16890 || broken(color_match(color, expected_broken[i * 4 + j], 1)),
16891 "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
16895 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16896 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
16898 IDirect3DPixelShader9_Release(ps);
16899 IDirect3DVertexShader9_Release(vs);
16902 refcount = IDirect3DDevice9_Release(device);
16903 ok(!refcount, "Device has %u references left.\n", refcount);
16904 done:
16905 IDirect3D9_Release(d3d);
16906 DestroyWindow(window);
16909 static void fog_special_test(void)
16911 static const struct
16913 struct vec3 position;
16914 D3DCOLOR diffuse;
16916 quad[] =
16918 {{ -1.0f, -1.0f, 0.0f}, 0xff00ff00},
16919 {{ -1.0f, 1.0f, 0.0f}, 0xff00ff00},
16920 {{ 1.0f, -1.0f, 1.0f}, 0xff00ff00},
16921 {{ 1.0f, 1.0f, 1.0f}, 0xff00ff00}
16923 static const struct
16925 DWORD vertexmode, tablemode;
16926 BOOL vs, ps;
16927 D3DCOLOR color_left, color_right;
16929 tests[] =
16931 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, FALSE, 0x00ff0000, 0x00ff0000},
16932 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, TRUE, 0x00ff0000, 0x00ff0000},
16933 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, FALSE, 0x00ff0000, 0x00ff0000},
16934 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, TRUE, 0x00ff0000, 0x00ff0000},
16936 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, FALSE, 0x0000ff00, 0x00ff0000},
16937 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, TRUE, 0x0000ff00, 0x00ff0000},
16938 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, FALSE, 0x0000ff00, 0x00ff0000},
16939 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, TRUE, 0x0000ff00, 0x00ff0000},
16941 static const DWORD pixel_shader_code[] =
16943 0xffff0101, /* ps_1_1 */
16944 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
16945 0x0000ffff
16947 static const DWORD vertex_shader_code[] =
16949 0xfffe0101, /* vs_1_1 */
16950 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
16951 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
16952 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
16953 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
16954 0x0000ffff
16956 static const D3DMATRIX identity =
16958 1.0f, 0.0f, 0.0f, 0.0f,
16959 0.0f, 1.0f, 0.0f, 0.0f,
16960 0.0f, 0.0f, 1.0f, 0.0f,
16961 0.0f, 0.0f, 0.0f, 1.0f,
16962 }}};
16963 union
16965 float f;
16966 DWORD d;
16967 } conv;
16968 DWORD color;
16969 HRESULT hr;
16970 unsigned int i;
16971 IDirect3DPixelShader9 *ps;
16972 IDirect3DVertexShader9 *vs;
16973 IDirect3DDevice9 *device;
16974 IDirect3D9 *d3d;
16975 ULONG refcount;
16976 D3DCAPS9 caps;
16977 HWND window;
16979 window = create_window();
16980 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16981 ok(!!d3d, "Failed to create a D3D object.\n");
16982 if (!(device = create_device(d3d, window, window, TRUE)))
16984 skip("Failed to create a D3D device, skipping tests.\n");
16985 goto done;
16988 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16989 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
16990 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
16992 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code, &vs);
16993 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
16995 else
16997 skip("Vertex Shaders not supported, skipping some fog tests.\n");
16998 vs = NULL;
17000 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
17002 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &ps);
17003 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
17005 else
17007 skip("Pixel Shaders not supported, skipping some fog tests.\n");
17008 ps = NULL;
17011 /* The table fog tests seem to depend on the projection matrix explicitly
17012 * being set to an identity matrix, even though that's the default.
17013 * (AMD Radeon HD 6310, Windows 7) */
17014 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
17015 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
17017 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
17018 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
17019 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
17020 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
17021 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
17022 ok(SUCCEEDED(hr), "Failed to enable fog, hr %#x.\n", hr);
17023 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffff0000);
17024 ok(SUCCEEDED(hr), "Failed to set fog color, hr %#x.\n", hr);
17026 conv.f = 0.5f;
17027 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, conv.d);
17028 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#x.\n", hr);
17029 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, conv.d);
17030 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#x.\n", hr);
17032 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
17034 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
17035 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
17037 if (!tests[i].vs)
17039 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
17040 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
17042 else if (vs)
17044 hr = IDirect3DDevice9_SetVertexShader(device, vs);
17045 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
17047 else
17049 continue;
17052 if (!tests[i].ps)
17054 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
17055 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
17057 else if (ps)
17059 hr = IDirect3DDevice9_SetPixelShader(device, ps);
17060 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
17062 else
17064 continue;
17067 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vertexmode);
17068 ok(SUCCEEDED(hr), "Failed to set fogvertexmode, hr %#x.\n", hr);
17069 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tablemode);
17070 ok(SUCCEEDED(hr), "Failed to set fogtablemode, hr %#x.\n", hr);
17072 hr = IDirect3DDevice9_BeginScene(device);
17073 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17074 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17075 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17076 hr = IDirect3DDevice9_EndScene(device);
17077 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17079 color = getPixelColor(device, 310, 240);
17080 ok(color_match(color, tests[i].color_left, 1),
17081 "Expected left color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_left, color, i);
17082 color = getPixelColor(device, 330, 240);
17083 ok(color_match(color, tests[i].color_right, 1),
17084 "Expected right color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_right, color, i);
17086 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17087 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
17090 if (vs)
17091 IDirect3DVertexShader9_Release(vs);
17092 if (ps)
17093 IDirect3DPixelShader9_Release(ps);
17094 refcount = IDirect3DDevice9_Release(device);
17095 ok(!refcount, "Device has %u references left.\n", refcount);
17096 done:
17097 IDirect3D9_Release(d3d);
17098 DestroyWindow(window);
17101 static void volume_srgb_test(void)
17103 HRESULT hr;
17104 unsigned int i, j;
17105 IDirect3DVolumeTexture9 *tex1, *tex2;
17106 D3DPOOL pool;
17107 D3DLOCKED_BOX locked_box;
17108 IDirect3DDevice9 *device;
17109 IDirect3D9 *d3d;
17110 D3DCOLOR color;
17111 ULONG refcount;
17112 HWND window;
17114 static const struct
17116 BOOL srgb;
17117 DWORD color;
17119 tests[] =
17121 /* Try toggling on and off */
17122 { FALSE, 0x007f7f7f },
17123 { TRUE, 0x00363636 },
17124 { FALSE, 0x007f7f7f },
17126 static const struct
17128 struct vec3 pos;
17129 struct vec3 texcrd;
17131 quad[] =
17133 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
17134 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
17135 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
17136 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
17139 window = create_window();
17140 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17141 ok(!!d3d, "Failed to create a D3D object.\n");
17142 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
17143 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_VOLUMETEXTURE, D3DFMT_A8R8G8B8) != D3D_OK)
17145 skip("D3DFMT_A8R8G8B8 volume textures with SRGBREAD not supported.\n");
17146 goto done;
17148 if (!(device = create_device(d3d, window, window, TRUE)))
17150 skip("Failed to create a D3D device, skipping tests.\n");
17151 goto done;
17154 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17155 ok(SUCCEEDED(hr), "Failed to set color op 0, hr %#x.\n", hr);
17156 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
17157 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17158 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
17159 ok(SUCCEEDED(hr), "Failed to set color op 0, hr %#x.\n", hr);
17160 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
17161 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
17163 for (i = 0; i < 2; i++)
17165 if (!i)
17166 pool = D3DPOOL_SYSTEMMEM;
17167 else
17168 pool = D3DPOOL_MANAGED;
17170 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, 0, D3DFMT_A8R8G8B8, pool, &tex1, NULL);
17171 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
17172 hr = IDirect3DVolumeTexture9_LockBox(tex1, 0, &locked_box, NULL, 0);
17173 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
17174 *((DWORD *)locked_box.pBits) = 0x7f7f7f7f;
17175 hr = IDirect3DVolumeTexture9_UnlockBox(tex1, 0);
17176 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
17178 if (!i)
17180 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, 0,
17181 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
17182 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
17183 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex1, (IDirect3DBaseTexture9 *)tex2);
17184 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17185 IDirect3DVolumeTexture9_Release(tex1);
17187 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex2);
17188 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17189 IDirect3DVolumeTexture9_Release(tex2);
17191 else
17193 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex1);
17194 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17195 IDirect3DVolumeTexture9_Release(tex1);
17198 for (j = 0; j < sizeof(tests) / sizeof(*tests); j++)
17200 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, tests[j].srgb);
17201 ok(SUCCEEDED(hr), "Failed to set srgb state, hr %#x.\n", hr);
17203 hr = IDirect3DDevice9_BeginScene(device);
17204 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17205 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17206 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17207 hr = IDirect3DDevice9_EndScene(device);
17208 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17210 color = getPixelColor(device, 320, 240);
17211 ok(color_match(color, tests[j].color, 2),
17212 "Expected color 0x%08x, got 0x%08x, i = %u, j = %u.\n", tests[j].color, color, i, j);
17214 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17215 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
17219 refcount = IDirect3DDevice9_Release(device);
17220 ok(!refcount, "Device has %u references left.\n", refcount);
17221 done:
17222 IDirect3D9_Release(d3d);
17223 DestroyWindow(window);
17226 static void volume_dxt5_test(void)
17228 IDirect3DVolumeTexture9 *texture;
17229 IDirect3DDevice9 *device;
17230 D3DLOCKED_BOX box;
17231 IDirect3D9 *d3d;
17232 unsigned int i;
17233 ULONG refcount;
17234 DWORD color;
17235 HWND window;
17236 HRESULT hr;
17238 static const char texture_data[] =
17240 /* A 8x4x2 texture consisting of 4 4x4 blocks. The colors of the blocks are red, green, blue and white. */
17241 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
17242 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
17243 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
17244 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
17246 static const struct
17248 struct vec3 position;
17249 struct vec3 texcrd;
17251 quads[] =
17253 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
17254 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
17255 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
17256 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
17258 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
17259 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
17260 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
17261 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
17263 static const DWORD expected_colors[] = {0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff};
17265 window = create_window();
17266 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17267 ok(!!d3d, "Failed to create a D3D object.\n");
17268 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17269 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_DXT5)))
17271 skip("DXT5 volume textures are not supported, skipping test.\n");
17272 goto done;
17274 if (!(device = create_device(d3d, window, window, TRUE)))
17276 skip("Failed to create a D3D device, skipping tests.\n");
17277 goto done;
17280 hr = IDirect3DDevice9_CreateVolumeTexture(device, 8, 4, 2, 1, 0, D3DFMT_DXT5,
17281 D3DPOOL_MANAGED, &texture, NULL);
17282 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
17284 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
17285 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
17286 memcpy(box.pBits, texture_data, sizeof(texture_data));
17287 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
17288 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
17290 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
17291 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
17292 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
17293 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17294 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17295 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17296 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
17297 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17298 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
17299 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17300 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
17301 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
17303 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
17304 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17305 hr = IDirect3DDevice9_BeginScene(device);
17306 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17307 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
17308 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17309 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
17310 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17311 hr = IDirect3DDevice9_EndScene(device);
17312 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17314 for (i = 0; i < 4; i++)
17316 color = getPixelColor(device, 80 + 160 * i, 240);
17317 ok (color_match(color, expected_colors[i], 1),
17318 "Expected color 0x%08x, got 0x%08x, case %u.\n", expected_colors[i], color, i);
17321 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17322 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17323 IDirect3DVolumeTexture9_Release(texture);
17324 refcount = IDirect3DDevice9_Release(device);
17325 ok(!refcount, "Device has %u references left.\n", refcount);
17326 done:
17327 IDirect3D9_Release(d3d);
17328 DestroyWindow(window);
17331 static void volume_v16u16_test(void)
17333 IDirect3DVolumeTexture9 *texture;
17334 IDirect3DPixelShader9 *shader;
17335 IDirect3DDevice9 *device;
17336 D3DLOCKED_BOX box;
17337 IDirect3D9 *d3d;
17338 unsigned int i;
17339 ULONG refcount;
17340 D3DCAPS9 caps;
17341 SHORT *texel;
17342 DWORD color;
17343 HWND window;
17344 HRESULT hr;
17346 static const struct
17348 struct vec3 position;
17349 struct vec3 texcrd;
17351 quads[] =
17353 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
17354 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
17355 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
17356 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
17358 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
17359 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
17360 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
17361 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
17363 static const DWORD shader_code[] =
17365 0xffff0101, /* ps_1_1 */
17366 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, */
17367 0x3f000000, 0x3f000000, /* 0.5, 0.5 */
17368 0x00000042, 0xb00f0000, /* tex t0 */
17369 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
17370 0x0000ffff /* end */
17373 window = create_window();
17374 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17375 ok(!!d3d, "Failed to create a D3D object.\n");
17376 if (!(device = create_device(d3d, window, window, TRUE)))
17378 skip("Failed to create a D3D device, skipping tests.\n");
17379 goto done;
17382 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17383 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17384 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
17386 skip("No ps_1_1 support, skipping tests.\n");
17387 IDirect3DDevice9_Release(device);
17388 goto done;
17390 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17391 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_V16U16)))
17393 skip("Volume V16U16 textures are not supported, skipping test.\n");
17394 IDirect3DDevice9_Release(device);
17395 goto done;
17398 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
17399 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
17400 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
17401 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
17402 hr = IDirect3DDevice9_SetPixelShader(device, shader);
17403 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
17404 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
17405 ok(SUCCEEDED(hr), "Failed to set filter, hr %#x.\n", hr);
17407 for (i = 0; i < 2; i++)
17409 D3DPOOL pool;
17411 if (i)
17412 pool = D3DPOOL_SYSTEMMEM;
17413 else
17414 pool = D3DPOOL_MANAGED;
17416 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
17417 pool, &texture, NULL);
17418 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
17420 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
17421 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
17423 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 0 * box.SlicePitch);
17424 texel[0] = 32767;
17425 texel[1] = 32767;
17426 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 0 * box.SlicePitch);
17427 texel[0] = -32768;
17428 texel[1] = 0;
17429 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 1 * box.SlicePitch);
17430 texel[0] = -16384;
17431 texel[1] = 16384;
17432 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 1 * box.SlicePitch);
17433 texel[0] = 0;
17434 texel[1] = 0;
17436 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
17437 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
17439 if (i)
17441 IDirect3DVolumeTexture9 *texture2;
17443 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
17444 D3DPOOL_DEFAULT, &texture2, NULL);
17445 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
17447 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture,
17448 (IDirect3DBaseTexture9 *)texture2);
17449 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17451 IDirect3DVolumeTexture9_Release(texture);
17452 texture = texture2;
17455 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
17456 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17458 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
17459 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17460 hr = IDirect3DDevice9_BeginScene(device);
17461 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17462 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
17463 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17464 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
17465 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17466 hr = IDirect3DDevice9_EndScene(device);
17467 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17469 color = getPixelColor(device, 120, 160);
17470 ok (color_match(color, 0x000080ff, 2),
17471 "Expected color 0x000080ff, got 0x%08x, V16U16 input -32768, 0.\n", color);
17472 color = getPixelColor(device, 120, 400);
17473 ok (color_match(color, 0x00ffffff, 2),
17474 "Expected color 0x00ffffff, got 0x%08x, V16U16 input 32767, 32767.\n", color);
17475 color = getPixelColor(device, 360, 160);
17476 ok (color_match(color, 0x007f7fff, 2),
17477 "Expected color 0x007f7fff, got 0x%08x, V16U16 input 0, 0.\n", color);
17478 color = getPixelColor(device, 360, 400);
17479 ok (color_match(color, 0x0040c0ff, 2),
17480 "Expected color 0x0040c0ff, got 0x%08x, V16U16 input -16384, 16384.\n", color);
17482 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17483 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17485 IDirect3DVolumeTexture9_Release(texture);
17488 IDirect3DPixelShader9_Release(shader);
17489 refcount = IDirect3DDevice9_Release(device);
17490 ok(!refcount, "Device has %u references left.\n", refcount);
17491 done:
17492 IDirect3D9_Release(d3d);
17493 DestroyWindow(window);
17496 static void add_dirty_rect_test_draw(IDirect3DDevice9 *device)
17498 HRESULT hr;
17499 static const struct
17501 struct vec3 position;
17502 struct vec2 texcoord;
17504 quad[] =
17506 {{-1.0, -1.0, 0.0}, {0.0, 0.0}},
17507 {{-1.0, 1.0, 0.0}, {0.0, 1.0}},
17508 {{ 1.0, -1.0, 0.0}, {1.0, 0.0}},
17509 {{ 1.0, 1.0, 0.0}, {1.0, 1.0}},
17512 hr = IDirect3DDevice9_BeginScene(device);
17513 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17514 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad, sizeof(*quad));
17515 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17516 hr = IDirect3DDevice9_EndScene(device);
17517 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17520 static void add_dirty_rect_test(void)
17522 HRESULT hr;
17523 IDirect3DTexture9 *tex_dst1, *tex_dst2, *tex_src_red, *tex_src_green,
17524 *tex_managed, *tex_dynamic;
17525 IDirect3DSurface9 *surface_dst2, *surface_src_green, *surface_src_red,
17526 *surface_managed0, *surface_managed1, *surface_dynamic;
17527 IDirect3DDevice9 *device;
17528 IDirect3D9 *d3d;
17529 unsigned int i;
17530 ULONG refcount;
17531 DWORD *texel;
17532 HWND window;
17533 D3DLOCKED_RECT locked_rect;
17534 static const RECT part_rect = {96, 96, 160, 160};
17535 DWORD color;
17537 window = create_window();
17538 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17539 ok(!!d3d, "Failed to create a D3D object.\n");
17540 if (!(device = create_device(d3d, window, window, TRUE)))
17542 skip("Failed to create a D3D device, skipping tests.\n");
17543 IDirect3D9_Release(d3d);
17544 DestroyWindow(window);
17545 return;
17548 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17549 D3DPOOL_DEFAULT, &tex_dst1, NULL);
17550 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17551 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17552 D3DPOOL_DEFAULT, &tex_dst2, NULL);
17553 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17554 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17555 D3DPOOL_SYSTEMMEM, &tex_src_red, NULL);
17556 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17557 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17558 D3DPOOL_SYSTEMMEM, &tex_src_green, NULL);
17559 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17560 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 2, 0, D3DFMT_X8R8G8B8,
17561 D3DPOOL_MANAGED, &tex_managed, NULL);
17562 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17563 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, D3DUSAGE_DYNAMIC,
17564 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex_dynamic, NULL);
17565 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17567 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dst2, 0, &surface_dst2);
17568 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17569 hr = IDirect3DTexture9_GetSurfaceLevel(tex_src_green, 0, &surface_src_green);
17570 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17571 hr = IDirect3DTexture9_GetSurfaceLevel(tex_src_red, 0, &surface_src_red);
17572 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17573 hr = IDirect3DTexture9_GetSurfaceLevel(tex_managed, 0, &surface_managed0);
17574 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17575 hr = IDirect3DTexture9_GetSurfaceLevel(tex_managed, 1, &surface_managed1);
17576 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17577 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dynamic, 0, &surface_dynamic);
17578 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17580 fill_surface(surface_src_red, 0x00ff0000, 0);
17581 fill_surface(surface_src_green, 0x0000ff00, 0);
17583 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
17584 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
17585 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17586 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17587 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
17588 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17589 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
17590 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
17592 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17593 (IDirect3DBaseTexture9 *)tex_dst1);
17594 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17596 /* The second UpdateTexture call writing to tex_dst2 is ignored because tex_src_green is not dirty. */
17597 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_red,
17598 (IDirect3DBaseTexture9 *)tex_dst2);
17599 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17600 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17601 (IDirect3DBaseTexture9 *)tex_dst2);
17602 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17604 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst1);
17605 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17606 add_dirty_rect_test_draw(device);
17607 color = getPixelColor(device, 320, 240);
17608 ok(color_match(color, 0x0000ff00, 1),
17609 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17610 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17611 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17613 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst2);
17614 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17615 add_dirty_rect_test_draw(device);
17616 color = getPixelColor(device, 320, 240);
17617 todo_wine ok(color_match(color, 0x00ff0000, 1),
17618 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17619 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17620 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17622 /* AddDirtyRect on the destination is ignored. */
17623 hr = IDirect3DTexture9_AddDirtyRect(tex_dst2, &part_rect);
17624 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17625 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17626 (IDirect3DBaseTexture9 *)tex_dst2);
17627 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17628 add_dirty_rect_test_draw(device);
17629 color = getPixelColor(device, 320, 240);
17630 todo_wine ok(color_match(color, 0x00ff0000, 1),
17631 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17632 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17633 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17635 hr = IDirect3DTexture9_AddDirtyRect(tex_dst2, NULL);
17636 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17637 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17638 (IDirect3DBaseTexture9 *)tex_dst2);
17639 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17640 add_dirty_rect_test_draw(device);
17641 color = getPixelColor(device, 320, 240);
17642 todo_wine ok(color_match(color, 0x00ff0000, 1),
17643 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17644 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17645 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17647 /* AddDirtyRect on the source makes UpdateTexture work. Partial rectangle
17648 * tracking is supported. */
17649 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, &part_rect);
17650 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17651 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17652 (IDirect3DBaseTexture9 *)tex_dst2);
17653 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17654 add_dirty_rect_test_draw(device);
17655 color = getPixelColor(device, 320, 240);
17656 ok(color_match(color, 0x0000ff00, 1),
17657 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17658 color = getPixelColor(device, 1, 1);
17659 todo_wine ok(color_match(color, 0x00ff0000, 1),
17660 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17661 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17662 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17664 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, NULL);
17665 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17666 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17667 (IDirect3DBaseTexture9 *)tex_dst2);
17668 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17669 add_dirty_rect_test_draw(device);
17670 color = getPixelColor(device, 1, 1);
17671 ok(color_match(color, 0x0000ff00, 1),
17672 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17674 /* Locks with NO_DIRTY_UPDATE are ignored. */
17675 fill_surface(surface_src_green, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE);
17676 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17677 (IDirect3DBaseTexture9 *)tex_dst2);
17678 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17679 add_dirty_rect_test_draw(device);
17680 color = getPixelColor(device, 320, 240);
17681 todo_wine ok(color_match(color, 0x0000ff00, 1),
17682 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17683 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17684 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17686 /* Readonly maps write to D3DPOOL_SYSTEMMEM, but don't record a dirty rectangle. */
17687 fill_surface(surface_src_green, 0x000000ff, D3DLOCK_READONLY);
17688 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17689 (IDirect3DBaseTexture9 *)tex_dst2);
17690 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17691 add_dirty_rect_test_draw(device);
17692 color = getPixelColor(device, 320, 240);
17693 todo_wine ok(color_match(color, 0x0000ff00, 1),
17694 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17695 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17696 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17698 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, NULL);
17699 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17700 (IDirect3DBaseTexture9 *)tex_dst2);
17701 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17702 add_dirty_rect_test_draw(device);
17703 color = getPixelColor(device, 320, 240);
17704 ok(color_match(color, 0x000000ff, 1),
17705 "Expected color 0x000000ff, got 0x%08x.\n", color);
17706 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17707 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17709 /* Maps without either of these flags record a dirty rectangle. */
17710 fill_surface(surface_src_green, 0x00ffffff, 0);
17711 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17712 (IDirect3DBaseTexture9 *)tex_dst2);
17713 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17714 add_dirty_rect_test_draw(device);
17715 color = getPixelColor(device, 320, 240);
17716 ok(color_match(color, 0x00ffffff, 1),
17717 "Expected color 0x00ffffff, got 0x%08x.\n", color);
17718 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17719 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17721 /* Partial LockRect works just like a partial AddDirtyRect call. */
17722 hr = IDirect3DTexture9_LockRect(tex_src_green, 0, &locked_rect, &part_rect, 0);
17723 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17724 texel = locked_rect.pBits;
17725 for (i = 0; i < 64; i++)
17726 texel[i] = 0x00ff00ff;
17727 for (i = 1; i < 64; i++)
17728 memcpy((BYTE *)locked_rect.pBits + i * locked_rect.Pitch, locked_rect.pBits, locked_rect.Pitch);
17729 hr = IDirect3DTexture9_UnlockRect(tex_src_green, 0);
17730 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17731 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17732 (IDirect3DBaseTexture9 *)tex_dst2);
17733 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17734 add_dirty_rect_test_draw(device);
17735 color = getPixelColor(device, 320, 240);
17736 ok(color_match(color, 0x00ff00ff, 1),
17737 "Expected color 0x00ff00ff, got 0x%08x.\n", color);
17738 color = getPixelColor(device, 1, 1);
17739 ok(color_match(color, 0x00ffffff, 1),
17740 "Expected color 0x00ffffff, got 0x%08x.\n", color);
17741 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17742 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17744 fill_surface(surface_src_red, 0x00ff0000, 0);
17745 fill_surface(surface_src_green, 0x0000ff00, 0);
17747 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17748 (IDirect3DBaseTexture9 *)tex_dst1);
17749 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17750 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst1);
17751 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17752 add_dirty_rect_test_draw(device);
17753 color = getPixelColor(device, 320, 240);
17754 ok(color_match(color, 0x0000ff00, 1),
17755 "Expected color 0x0000ff00, got 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 /* UpdateSurface ignores the missing dirty marker. */
17760 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_red,
17761 (IDirect3DBaseTexture9 *)tex_dst2);
17762 hr = IDirect3DDevice9_UpdateSurface(device, surface_src_green, NULL, surface_dst2, NULL);
17763 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
17764 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst2);
17765 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17766 add_dirty_rect_test_draw(device);
17767 color = getPixelColor(device, 320, 240);
17768 ok(color_match(color, 0x0000ff00, 1),
17769 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17770 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17771 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17773 /* Tests with managed textures. */
17774 fill_surface(surface_managed0, 0x00ff0000, 0);
17775 fill_surface(surface_managed1, 0x00ff0000, 0);
17776 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_managed);
17777 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17778 add_dirty_rect_test_draw(device);
17779 color = getPixelColor(device, 320, 240);
17780 ok(color_match(color, 0x00ff0000, 1),
17781 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17782 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17783 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17784 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
17785 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
17786 add_dirty_rect_test_draw(device);
17787 color = getPixelColor(device, 320, 240);
17788 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
17789 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17790 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17792 /* Managed textures also honor D3DLOCK_NO_DIRTY_UPDATE. */
17793 fill_surface(surface_managed0, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE);
17794 fill_surface(surface_managed1, 0x000000ff, D3DLOCK_NO_DIRTY_UPDATE);
17795 add_dirty_rect_test_draw(device);
17796 color = getPixelColor(device, 320, 240);
17797 ok(color_match(color, 0x00ff0000, 1),
17798 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17799 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17800 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17801 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
17802 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
17803 add_dirty_rect_test_draw(device);
17804 color = getPixelColor(device, 320, 240);
17805 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
17806 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17807 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17809 /* AddDirtyRect uploads the new contents.
17810 * Side note, not tested in the test: Partial surface updates work, and two separate
17811 * dirty rectangles are tracked individually. Tested on Nvidia Kepler, other drivers
17812 * untested. */
17813 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
17814 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17815 add_dirty_rect_test_draw(device);
17816 color = getPixelColor(device, 320, 240);
17817 ok(color_match(color, 0x0000ff00, 1),
17818 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17819 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17820 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17821 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
17822 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
17823 add_dirty_rect_test_draw(device);
17824 color = getPixelColor(device, 320, 240);
17825 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
17826 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17827 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17829 /* So does EvictManagedResources. */
17830 fill_surface(surface_managed0, 0x00ffff00, D3DLOCK_NO_DIRTY_UPDATE);
17831 fill_surface(surface_managed1, 0x00ff00ff, D3DLOCK_NO_DIRTY_UPDATE);
17832 hr = IDirect3DDevice9_EvictManagedResources(device);
17833 ok(SUCCEEDED(hr), "Failed to evict managed resources, hr %#x.\n", hr);
17834 add_dirty_rect_test_draw(device);
17835 color = getPixelColor(device, 320, 240);
17836 ok(color_match(color, 0x00ff00ff, 1), "Got unexpected color 0x%08x.\n", color);
17837 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17838 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17839 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
17840 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
17841 add_dirty_rect_test_draw(device);
17842 color = getPixelColor(device, 320, 240);
17843 ok(color_match(color, 0x00ffff00, 1), "Got unexpected color 0x%08x.\n", color);
17844 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17845 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17847 /* Tests with dynamic textures */
17848 fill_surface(surface_dynamic, 0x0000ffff, 0);
17849 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dynamic);
17850 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17851 add_dirty_rect_test_draw(device);
17852 color = getPixelColor(device, 320, 240);
17853 ok(color_match(color, 0x0000ffff, 1),
17854 "Expected color 0x0000ffff, got 0x%08x.\n", color);
17855 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17856 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17858 /* Dynamic textures don't honor D3DLOCK_NO_DIRTY_UPDATE. */
17859 fill_surface(surface_dynamic, 0x00ffff00, D3DLOCK_NO_DIRTY_UPDATE);
17860 add_dirty_rect_test_draw(device);
17861 color = getPixelColor(device, 320, 240);
17862 ok(color_match(color, 0x00ffff00, 1),
17863 "Expected color 0x00ffff00, got 0x%08x.\n", color);
17864 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17865 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17867 /* AddDirtyRect on a locked texture is allowed. */
17868 hr = IDirect3DTexture9_LockRect(tex_src_red, 0, &locked_rect, NULL, 0);
17869 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17870 hr = IDirect3DTexture9_AddDirtyRect(tex_src_red, NULL);
17871 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17872 hr = IDirect3DTexture9_UnlockRect(tex_src_red, 0);
17873 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17875 /* Redundant AddDirtyRect calls are ok. */
17876 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
17877 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17878 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
17879 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17881 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
17882 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17883 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
17884 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17885 IDirect3DSurface9_Release(surface_dst2);
17886 IDirect3DSurface9_Release(surface_managed1);
17887 IDirect3DSurface9_Release(surface_managed0);
17888 IDirect3DSurface9_Release(surface_src_red);
17889 IDirect3DSurface9_Release(surface_src_green);
17890 IDirect3DSurface9_Release(surface_dynamic);
17891 IDirect3DTexture9_Release(tex_src_red);
17892 IDirect3DTexture9_Release(tex_src_green);
17893 IDirect3DTexture9_Release(tex_dst1);
17894 IDirect3DTexture9_Release(tex_dst2);
17895 IDirect3DTexture9_Release(tex_managed);
17896 IDirect3DTexture9_Release(tex_dynamic);
17897 refcount = IDirect3DDevice9_Release(device);
17898 ok(!refcount, "Device has %u references left.\n", refcount);
17899 IDirect3D9_Release(d3d);
17900 DestroyWindow(window);
17903 static void test_per_stage_constant(void)
17905 IDirect3DDevice9 *device;
17906 IDirect3D9 *d3d;
17907 D3DCOLOR color;
17908 ULONG refcount;
17909 D3DCAPS9 caps;
17910 HWND window;
17911 HRESULT hr;
17913 static const struct
17915 struct vec3 position;
17916 D3DCOLOR diffuse;
17918 quad[] =
17920 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
17921 {{-1.0f, 1.0f, 0.1f}, 0xffff0000},
17922 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
17923 {{ 1.0f, 1.0f, 0.1f}, 0xffff0000},
17926 window = create_window();
17927 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17928 ok(!!d3d, "Failed to create a D3D object.\n");
17929 if (!(device = create_device(d3d, window, window, TRUE)))
17931 skip("Failed to create a D3D device, skipping tests.\n");
17932 goto done;
17935 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17936 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17937 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_PERSTAGECONSTANT))
17939 skip("Per-stage constants not supported, skipping tests.\n");
17940 IDirect3DDevice9_Release(device);
17941 goto done;
17944 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
17945 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
17946 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
17947 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17948 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
17949 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17950 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
17951 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17952 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
17953 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17955 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_CONSTANT, 0x80a1b2c3);
17956 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17957 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT);
17958 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17959 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17960 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17962 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17963 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17965 hr = IDirect3DDevice9_BeginScene(device);
17966 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17967 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17968 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17969 hr = IDirect3DDevice9_EndScene(device);
17970 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17972 color = getPixelColor(device, 320, 240);
17973 ok(color_match(color, 0x00a1b2c3, 1), "Got unexpected color 0x%08x.\n", color);
17974 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17975 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17977 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT | D3DTA_COMPLEMENT);
17978 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17980 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17981 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17983 hr = IDirect3DDevice9_BeginScene(device);
17984 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17985 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17986 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17987 hr = IDirect3DDevice9_EndScene(device);
17988 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17990 color = getPixelColor(device, 320, 240);
17991 ok(color_match(color, 0x005e4d3c, 1), "Got unexpected color 0x%08x.\n", color);
17992 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17993 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17995 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT | D3DTA_ALPHAREPLICATE);
17996 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17998 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17999 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18001 hr = IDirect3DDevice9_BeginScene(device);
18002 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18003 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18004 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18005 hr = IDirect3DDevice9_EndScene(device);
18006 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18008 color = getPixelColor(device, 320, 240);
18009 ok(color_match(color, 0x00808080, 1), "Got unexpected color 0x%08x.\n", color);
18010 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18011 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18013 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_CONSTANT);
18014 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
18015 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
18016 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
18017 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CURRENT);
18018 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
18020 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
18021 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18023 hr = IDirect3DDevice9_BeginScene(device);
18024 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18025 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18026 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18027 hr = IDirect3DDevice9_EndScene(device);
18028 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18030 color = getPixelColor(device, 320, 240);
18031 ok(color_match(color, 0x0080007f, 1), "Got unexpected color 0x%08x.\n", color);
18032 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18033 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18035 refcount = IDirect3DDevice9_Release(device);
18036 ok(!refcount, "Device has %u references left.\n", refcount);
18037 done:
18038 IDirect3D9_Release(d3d);
18039 DestroyWindow(window);
18042 static void test_3dc_formats(void)
18044 static const char ati1n_data[] =
18046 /* A 4x4 texture with the color component at 50%. */
18047 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
18049 static const char ati2n_data[] =
18051 /* A 8x4 texture consisting of 2 4x4 blocks. The first block has 50% first color component,
18052 * 0% second component. Second block is the opposite. */
18053 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
18054 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
18056 static const struct
18058 struct vec3 position;
18059 struct vec2 texcoord;
18061 quads[] =
18063 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
18064 {{-1.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
18065 {{ 0.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
18066 {{ 0.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
18068 {{ 0.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
18069 {{ 0.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
18070 {{ 1.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
18071 {{ 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
18073 static const DWORD ati1n_fourcc = MAKEFOURCC('A','T','I','1');
18074 static const DWORD ati2n_fourcc = MAKEFOURCC('A','T','I','2');
18075 static const struct
18077 struct vec2 position;
18078 D3DCOLOR amd_r500;
18079 D3DCOLOR amd_r600;
18080 D3DCOLOR nvidia_old;
18081 D3DCOLOR nvidia_new;
18083 expected_colors[] =
18085 {{ 80, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
18086 {{240, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
18087 {{400, 240}, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff},
18088 {{560, 240}, 0x007f00ff, 0x007f00ff, 0x007f00ff, 0x007f00ff},
18090 IDirect3D9 *d3d;
18091 IDirect3DDevice9 *device;
18092 IDirect3DTexture9 *ati1n_texture, *ati2n_texture;
18093 D3DCAPS9 caps;
18094 D3DLOCKED_RECT rect;
18095 D3DCOLOR color;
18096 ULONG refcount;
18097 HWND window;
18098 HRESULT hr;
18099 unsigned int i;
18101 window = create_window();
18102 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18103 ok(!!d3d, "Failed to create a D3D object.\n");
18104 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
18105 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati1n_fourcc)))
18107 skip("ATI1N textures are not supported, skipping test.\n");
18108 goto done;
18110 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
18111 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati2n_fourcc)))
18113 skip("ATI2N textures are not supported, skipping test.\n");
18114 goto done;
18116 if (!(device = create_device(d3d, window, window, TRUE)))
18118 skip("Failed to create a D3D device, skipping tests.\n");
18119 goto done;
18121 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18122 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18123 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
18125 skip("D3DTA_TEMP not supported, skipping tests.\n");
18126 IDirect3DDevice9_Release(device);
18127 goto done;
18130 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, ati1n_fourcc,
18131 D3DPOOL_MANAGED, &ati1n_texture, NULL);
18132 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
18134 hr = IDirect3DTexture9_LockRect(ati1n_texture, 0, &rect, NULL, 0);
18135 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
18136 memcpy(rect.pBits, ati1n_data, sizeof(ati1n_data));
18137 hr = IDirect3DTexture9_UnlockRect(ati1n_texture, 0);
18138 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
18140 hr = IDirect3DDevice9_CreateTexture(device, 8, 4, 1, 0, ati2n_fourcc,
18141 D3DPOOL_MANAGED, &ati2n_texture, NULL);
18142 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
18144 hr = IDirect3DTexture9_LockRect(ati2n_texture, 0, &rect, NULL, 0);
18145 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
18146 memcpy(rect.pBits, ati2n_data, sizeof(ati2n_data));
18147 hr = IDirect3DTexture9_UnlockRect(ati2n_texture, 0);
18148 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
18150 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0));
18151 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
18152 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
18153 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
18154 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
18155 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
18156 /* The temporary register is initialized to 0. */
18157 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TEMP);
18158 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
18159 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
18160 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#x.\n", hr);
18161 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
18162 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#x.\n", hr);
18163 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
18164 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
18165 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
18166 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
18168 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
18169 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18170 hr = IDirect3DDevice9_BeginScene(device);
18171 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18172 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)ati1n_texture);
18173 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
18174 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
18175 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18176 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)ati2n_texture);
18177 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
18178 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
18179 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18180 hr = IDirect3DDevice9_EndScene(device);
18181 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18183 for (i = 0; i < 4; ++i)
18185 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
18186 ok (color_match(color, expected_colors[i].amd_r500, 1)
18187 || color_match(color, expected_colors[i].amd_r600, 1)
18188 || color_match(color, expected_colors[i].nvidia_old, 1)
18189 || color_match(color, expected_colors[i].nvidia_new, 1),
18190 "Got unexpected color 0x%08x, case %u.\n", color, i);
18193 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18194 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18195 IDirect3DTexture9_Release(ati2n_texture);
18196 IDirect3DTexture9_Release(ati1n_texture);
18197 refcount = IDirect3DDevice9_Release(device);
18198 ok(!refcount, "Device has %u references left.\n", refcount);
18200 done:
18201 IDirect3D9_Release(d3d);
18202 DestroyWindow(window);
18205 static void test_fog_interpolation(void)
18207 HRESULT hr;
18208 IDirect3DDevice9 *device;
18209 IDirect3D9 *d3d;
18210 ULONG refcount;
18211 HWND window;
18212 D3DCOLOR color;
18213 static const struct
18215 struct vec3 position;
18216 D3DCOLOR diffuse;
18217 D3DCOLOR specular;
18219 quad[] =
18221 {{-1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff000000},
18222 {{-1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff000000},
18223 {{ 1.0f, -1.0f, 1.0f}, 0xffff0000, 0x00000000},
18224 {{ 1.0f, 1.0f, 1.0f}, 0xffff0000, 0x00000000},
18226 union
18228 DWORD d;
18229 float f;
18230 } conv;
18231 unsigned int i;
18232 static const struct
18234 D3DFOGMODE vfog, tfog;
18235 D3DSHADEMODE shade;
18236 D3DCOLOR middle_color;
18237 BOOL todo;
18239 tests[] =
18241 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, FALSE},
18242 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, FALSE},
18243 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, TRUE},
18244 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, TRUE},
18245 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
18246 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
18247 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
18248 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
18250 static const D3DMATRIX ident_mat =
18252 1.0f, 0.0f, 0.0f, 0.0f,
18253 0.0f, 1.0f, 0.0f, 0.0f,
18254 0.0f, 0.0f, 1.0f, 0.0f,
18255 0.0f, 0.0f, 0.0f, 1.0f
18256 }}};
18257 D3DCAPS9 caps;
18259 window = create_window();
18260 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18261 ok(!!d3d, "Failed to create a D3D object.\n");
18263 if (!(device = create_device(d3d, window, window, TRUE)))
18265 skip("Failed to create a D3D device, skipping tests.\n");
18266 IDirect3D9_Release(d3d);
18267 DestroyWindow(window);
18268 return;
18271 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18272 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18273 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
18274 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
18276 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
18277 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
18278 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18279 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18280 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
18281 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18282 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
18283 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18284 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
18285 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18286 conv.f = 5.0;
18287 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGDENSITY, conv.d);
18288 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18290 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
18291 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
18292 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
18293 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
18294 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x000000ff);
18295 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18297 /* Some of the tests seem to depend on the projection matrix explicitly
18298 * being set to an identity matrix, even though that's the default.
18299 * (AMD Radeon X1600, AMD Radeon HD 6310, Windows 7). Without this,
18300 * the drivers seem to use a static z = 1.0 input for the fog equation.
18301 * The input value is independent of the actual z and w component of
18302 * the vertex position. */
18303 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
18304 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
18306 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
18308 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
18309 continue;
18311 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00808080, 0.0f, 0);
18312 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18314 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shade);
18315 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18316 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
18317 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18318 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
18319 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18320 hr = IDirect3DDevice9_BeginScene(device);
18321 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18322 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18323 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18324 hr = IDirect3DDevice9_EndScene(device);
18325 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18327 color = getPixelColor(device, 0, 240);
18328 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
18329 color = getPixelColor(device, 320, 240);
18330 todo_wine_if (tests[i].todo)
18331 ok(color_match(color, tests[i].middle_color, 2),
18332 "Got unexpected color 0x%08x, case %u.\n", color, i);
18333 color = getPixelColor(device, 639, 240);
18334 ok(color_match(color, 0x0000fd02, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
18335 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18336 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18339 refcount = IDirect3DDevice9_Release(device);
18340 ok(!refcount, "Device has %u references left.\n", refcount);
18341 IDirect3D9_Release(d3d);
18342 DestroyWindow(window);
18345 static void test_negative_fixedfunction_fog(void)
18347 HRESULT hr;
18348 IDirect3DDevice9 *device;
18349 IDirect3D9 *d3d;
18350 ULONG refcount;
18351 HWND window;
18352 D3DCOLOR color;
18353 static const struct
18355 struct vec3 position;
18356 D3DCOLOR diffuse;
18358 quad[] =
18360 {{-1.0f, -1.0f, -0.5f}, 0xffff0000},
18361 {{-1.0f, 1.0f, -0.5f}, 0xffff0000},
18362 {{ 1.0f, -1.0f, -0.5f}, 0xffff0000},
18363 {{ 1.0f, 1.0f, -0.5f}, 0xffff0000},
18365 static const struct
18367 struct vec4 position;
18368 D3DCOLOR diffuse;
18370 tquad[] =
18372 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
18373 {{640.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
18374 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
18375 {{640.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
18377 unsigned int i;
18378 static const D3DMATRIX zero =
18380 1.0f, 0.0f, 0.0f, 0.0f,
18381 0.0f, 1.0f, 0.0f, 0.0f,
18382 0.0f, 0.0f, 0.0f, 0.0f,
18383 0.0f, 0.0f, 0.0f, 1.0f
18384 }}};
18385 /* Needed to make AMD drivers happy. Yeah, it is not supposed to
18386 * have an effect on RHW draws. */
18387 static const D3DMATRIX identity =
18389 1.0f, 0.0f, 0.0f, 0.0f,
18390 0.0f, 1.0f, 0.0f, 0.0f,
18391 0.0f, 0.0f, 1.0f, 0.0f,
18392 0.0f, 0.0f, 0.0f, 1.0f
18393 }}};
18394 static const struct
18396 DWORD pos_type;
18397 const void *quad;
18398 size_t stride;
18399 const D3DMATRIX *matrix;
18400 union
18402 float f;
18403 DWORD d;
18404 } start, end;
18405 D3DFOGMODE vfog, tfog;
18406 DWORD color, color_broken, color_broken2;
18408 tests[] =
18410 /* Run the XYZRHW tests first. Depth clamping is broken after RHW draws on the testbot.
18412 * Geforce8+ GPUs on Windows abs() table fog, everything else does not. */
18413 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, { 0.0f}, {1.0f},
18414 D3DFOG_NONE, D3DFOG_LINEAR, 0x00ff0000, 0x00808000, 0x00808000},
18415 /* r200 GPUs and presumably all d3d8 and older HW clamp the fog
18416 * parameters to 0.0 and 1.0 in the table fog case. */
18417 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, {-1.0f}, {0.0f},
18418 D3DFOG_NONE, D3DFOG_LINEAR, 0x00808000, 0x00ff0000, 0x0000ff00},
18419 /* test_fog_interpolation shows that vertex fog evaluates the fog
18420 * equation in the vertex pipeline. Start = -1.0 && end = 0.0 shows
18421 * that the abs happens before the fog equation is evaluated.
18423 * Vertex fog abs() behavior is the same on all GPUs. */
18424 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
18425 D3DFOG_LINEAR, D3DFOG_NONE, 0x00808000, 0x00808000, 0x00808000},
18426 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, {-1.0f}, {0.0f},
18427 D3DFOG_LINEAR, D3DFOG_NONE, 0x0000ff00, 0x0000ff00, 0x0000ff00},
18428 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
18429 D3DFOG_EXP, D3DFOG_NONE, 0x009b6400, 0x009b6400, 0x009b6400},
18431 D3DCAPS9 caps;
18433 window = create_window();
18434 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18435 ok(!!d3d, "Failed to create a D3D object.\n");
18437 if (!(device = create_device(d3d, window, window, TRUE)))
18439 skip("Failed to create a D3D device, skipping tests.\n");
18440 IDirect3D9_Release(d3d);
18441 DestroyWindow(window);
18442 return;
18445 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18446 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18447 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
18448 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests.\n");
18450 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18451 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18452 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
18453 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18454 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
18455 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18456 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
18457 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18458 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
18459 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
18461 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
18463 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
18464 continue;
18466 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
18467 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18469 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, tests[i].matrix);
18470 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
18471 hr = IDirect3DDevice9_SetFVF(device, tests[i].pos_type | D3DFVF_DIFFUSE);
18472 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
18473 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, tests[i].start.d);
18474 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18475 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, tests[i].end.d);
18476 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18477 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
18478 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18479 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
18480 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18482 hr = IDirect3DDevice9_BeginScene(device);
18483 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18484 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tests[i].quad, tests[i].stride);
18485 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18486 hr = IDirect3DDevice9_EndScene(device);
18487 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18489 color = getPixelColor(device, 320, 240);
18490 ok(color_match(color, tests[i].color, 2) || broken(color_match(color, tests[i].color_broken, 2))
18491 || broken(color_match(color, tests[i].color_broken2, 2)),
18492 "Got unexpected color 0x%08x, case %u.\n", color, i);
18493 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18494 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18497 refcount = IDirect3DDevice9_Release(device);
18498 ok(!refcount, "Device has %u references left.\n", refcount);
18499 IDirect3D9_Release(d3d);
18500 DestroyWindow(window);
18503 static void test_position_index(void)
18505 static const D3DVERTEXELEMENT9 decl_elements[] =
18507 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
18508 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 1},
18509 D3DDECL_END()
18511 /* Declaring (and using) a position1 output semantic in a VS fails at draw time on AMD
18512 * but works on Nvidia.
18513 * MSDN is not consistent on this point. */
18514 static const DWORD vs_code[] =
18516 0xfffe0300, /* vs_3_0 */
18517 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
18518 0x0200001f, 0x80010000, 0x900f0001, /* dcl_position1 v1 */
18519 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position0 o0 */
18520 0x0200001f, 0x80010000, 0xe00f0001, /* dcl_position1 o1 */
18521 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
18522 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
18523 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
18524 0x02000001, 0xe00f0002, 0x90e40001, /* mov o2, v1 */
18525 0x0000ffff /* end */
18527 static const DWORD vs_code_2[] =
18529 0xfffe0300, /* vs_3_0 */
18530 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
18531 0x0200001f, 0x80010000, 0x900f0001, /* dcl_position1 v1 */
18532 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position0 o0 */
18533 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
18534 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
18535 0x02000001, 0xe00f0002, 0x90e40001, /* mov o2, v1 */
18536 0x0000ffff /* end */
18538 static const DWORD ps_code[] =
18540 0xffff0300, /* ps_3_0 */
18541 0x0200001f, 0x80010000, 0x900f0000, /* dcl_position1 v0 */
18542 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
18543 0x0000ffff /* end */
18545 static const DWORD ps_code_2[] =
18547 0xffff0300, /* ps_3_0 */
18548 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
18549 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
18550 0x0000ffff /* end */
18552 /* This one is considered invalid by the native shader assembler. */
18553 static const DWORD ps_code_bad[] =
18555 0xffff0300, /* ps_3_0 */
18556 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
18557 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
18558 0x0000ffff /* end */
18560 static const struct
18562 struct vec3 position;
18563 struct vec3 position1;
18565 quad[] =
18567 {{-1.0f, -1.0f, 0.5f}, {1.0f, 0.0f, 0.0f}},
18568 {{-1.0f, 1.0f, 0.5f}, {1.0f, 0.0f, 0.0f}},
18569 {{ 1.0f, -1.0f, 0.5f}, {0.0f, 1.0f, 0.0f}},
18570 {{ 1.0f, 1.0f, 0.5f}, {0.0f, 1.0f, 0.0f}},
18572 static const struct
18574 struct vec2 position;
18575 D3DCOLOR expected_color;
18576 D3DCOLOR broken_color;
18578 expected_colors[] =
18580 {{ 80, 240}, 0x00df2000, 0x00ff00ff},
18581 {{240, 240}, 0x009f6000, 0x00ff00ff},
18582 {{400, 240}, 0x00609f00, 0x00ff00ff},
18583 {{560, 240}, 0x0020df00, 0x00ff00ff},
18585 IDirect3D9 *d3d;
18586 IDirect3DDevice9 *device;
18587 IDirect3DVertexDeclaration9 *vertex_declaration;
18588 IDirect3DVertexShader9 *vs, *vs2;
18589 IDirect3DPixelShader9 *ps, *ps2;
18590 D3DCAPS9 caps;
18591 D3DCOLOR color;
18592 ULONG refcount;
18593 HWND window;
18594 HRESULT hr;
18595 unsigned int i;
18597 window = create_window();
18598 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18599 ok(!!d3d, "Failed to create a D3D object.\n");
18600 if (!(device = create_device(d3d, window, window, TRUE)))
18602 skip("Failed to create a D3D device, skipping tests.\n");
18603 goto done;
18606 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18607 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18608 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0)
18609 || caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
18611 skip("Shader model 3.0 unsupported, skipping tests.\n");
18612 IDirect3DDevice9_Release(device);
18613 goto done;
18616 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
18617 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed, hr %#x\n", hr);
18619 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
18620 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x\n", hr);
18622 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
18623 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
18624 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code_2, &vs2);
18625 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
18627 hr = IDirect3DDevice9_SetVertexShader(device, vs);
18628 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
18630 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_bad, &ps);
18631 ok(hr == D3DERR_INVALIDCALL, "CreatePixelShader returned hr %#x.\n", hr);
18633 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
18634 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
18635 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_2, &ps2);
18636 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
18638 hr = IDirect3DDevice9_SetPixelShader(device, ps);
18639 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18641 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
18642 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18643 hr = IDirect3DDevice9_BeginScene(device);
18644 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18645 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18646 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18647 hr = IDirect3DDevice9_EndScene(device);
18648 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18650 for (i = 0; i < sizeof(expected_colors) / sizeof(expected_colors[0]); ++i)
18652 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
18653 ok (color_match(color, expected_colors[i].expected_color, 1)
18654 || broken(color_match(color, expected_colors[i].broken_color, 1)),
18655 "Got unexpected color 0x%08x, case %u.\n", color, i);
18658 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
18659 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18661 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
18662 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18663 hr = IDirect3DDevice9_BeginScene(device);
18664 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18665 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18666 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18667 hr = IDirect3DDevice9_EndScene(device);
18668 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18670 for (i = 0; i < sizeof(expected_colors) / sizeof(expected_colors[0]); ++i)
18672 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
18673 ok (color_match(color, expected_colors[i].expected_color, 1)
18674 || broken(color_match(color, expected_colors[i].broken_color, 1)),
18675 "Got unexpected color 0x%08x, case %u.\n", color, i);
18678 hr = IDirect3DDevice9_SetVertexShader(device, vs2);
18679 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
18681 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
18682 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18683 hr = IDirect3DDevice9_BeginScene(device);
18684 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18685 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18686 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18687 hr = IDirect3DDevice9_EndScene(device);
18688 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18690 for (i = 0; i < sizeof(expected_colors) / sizeof(expected_colors[0]); ++i)
18692 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
18693 ok (color_match(color, expected_colors[i].expected_color, 1),
18694 "Got unexpected color 0x%08x, case %u.\n", color, i);
18697 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18698 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18700 IDirect3DPixelShader9_Release(ps2);
18701 IDirect3DPixelShader9_Release(ps);
18702 IDirect3DVertexShader9_Release(vs2);
18703 IDirect3DVertexShader9_Release(vs);
18704 IDirect3DVertexDeclaration9_Release(vertex_declaration);
18705 refcount = IDirect3DDevice9_Release(device);
18706 ok(!refcount, "Device has %u references left.\n", refcount);
18708 done:
18709 IDirect3D9_Release(d3d);
18710 DestroyWindow(window);
18713 static void test_table_fog_zw(void)
18715 HRESULT hr;
18716 IDirect3DDevice9 *device;
18717 IDirect3D9 *d3d;
18718 ULONG refcount;
18719 HWND window;
18720 D3DCOLOR color;
18721 D3DCAPS9 caps;
18722 static struct
18724 struct vec4 position;
18725 D3DCOLOR diffuse;
18727 quad[] =
18729 {{ 0.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
18730 {{640.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
18731 {{ 0.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
18732 {{640.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
18734 static const D3DMATRIX identity =
18736 1.0f, 0.0f, 0.0f, 0.0f,
18737 0.0f, 1.0f, 0.0f, 0.0f,
18738 0.0f, 0.0f, 1.0f, 0.0f,
18739 0.0f, 0.0f, 0.0f, 1.0f
18740 }}};
18741 static const struct
18743 float z, w;
18744 D3DZBUFFERTYPE z_test;
18745 D3DCOLOR color;
18747 tests[] =
18749 {0.7f, 0.0f, D3DZB_TRUE, 0x004cb200},
18750 {0.7f, 0.0f, D3DZB_FALSE, 0x004cb200},
18751 {0.7f, 0.3f, D3DZB_TRUE, 0x004cb200},
18752 {0.7f, 0.3f, D3DZB_FALSE, 0x004cb200},
18753 {0.7f, 3.0f, D3DZB_TRUE, 0x004cb200},
18754 {0.7f, 3.0f, D3DZB_FALSE, 0x004cb200},
18755 {0.3f, 0.0f, D3DZB_TRUE, 0x00b24c00},
18756 {0.3f, 0.0f, D3DZB_FALSE, 0x00b24c00},
18758 unsigned int i;
18760 window = create_window();
18761 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18762 ok(!!d3d, "Failed to create a D3D object.\n");
18764 if (!(device = create_device(d3d, window, window, TRUE)))
18766 skip("Failed to create a D3D device, skipping tests.\n");
18767 IDirect3D9_Release(d3d);
18768 DestroyWindow(window);
18769 return;
18772 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18773 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18774 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
18776 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping POSITIONT table fog test.\n");
18777 goto done;
18780 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18781 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18782 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
18783 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18784 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
18785 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18786 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
18787 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
18788 /* Work around an AMD Windows driver bug. Needs a proj matrix applied redundantly. */
18789 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
18790 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
18791 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
18792 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18793 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
18794 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
18796 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
18798 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
18799 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18801 quad[0].position.z = tests[i].z;
18802 quad[1].position.z = tests[i].z;
18803 quad[2].position.z = tests[i].z;
18804 quad[3].position.z = tests[i].z;
18805 quad[0].position.w = tests[i].w;
18806 quad[1].position.w = tests[i].w;
18807 quad[2].position.w = tests[i].w;
18808 quad[3].position.w = tests[i].w;
18809 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, tests[i].z_test);
18810 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18812 hr = IDirect3DDevice9_BeginScene(device);
18813 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18814 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
18815 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18816 hr = IDirect3DDevice9_EndScene(device);
18817 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18819 color = getPixelColor(device, 320, 240);
18820 ok(color_match(color, tests[i].color, 2),
18821 "Got unexpected color 0x%08x, expected 0x%08x, case %u.\n", color, tests[i].color, i);
18822 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18823 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18826 done:
18827 refcount = IDirect3DDevice9_Release(device);
18828 ok(!refcount, "Device has %u references left.\n", refcount);
18829 IDirect3D9_Release(d3d);
18830 DestroyWindow(window);
18833 static void test_signed_formats(void)
18835 IDirect3DDevice9 *device;
18836 HWND window;
18837 HRESULT hr;
18838 unsigned int i, j, x, y;
18839 IDirect3DTexture9 *texture, *texture_sysmem;
18840 IDirect3DSurface9 *src_surface, *dst_surface;
18841 D3DLOCKED_RECT locked_rect;
18842 IDirect3DPixelShader9 *shader, *shader_alpha;
18843 IDirect3D9 *d3d;
18844 D3DCOLOR color;
18845 D3DCAPS9 caps;
18846 ULONG refcount;
18848 /* The input data was designed for D3DFMT_L6V5U5 and then transferred
18849 * to the other formats because L6V5U5 is the lowest precision format.
18850 * It tests the extreme values -1.0 (-16) and 1.0 (15) for U/V and
18851 * 0.0 (0) and 1.0 (63) for L, the neutral point 0 as well as -1 and 1.
18852 * Some other intermediate values are tested too. The input value -15
18853 * (min + 1) is tested as well. Unlike what OpenGL 4.4 says in section
18854 * 2.3.4.1, this value does not represent -1.0. In the interest of re-
18855 * using the expected output data the 8 bit and 16 bit values in V8U8
18856 * and V16U16 match (post-normalization) the 5 bit input values. Thus
18857 * -1, 1 and -127 are not tested in V8U8.
18859 * 8 bit specific values like -127 are tested in the Q channel of
18860 * D3DFMT_Q8W8V8U8. Here d3d seems to follow the rules from the GL
18861 * spec. AMD's r200 is broken though and returns a value < -1.0 for
18862 * -128. The difference between using -127 or -128 as the lowest
18863 * possible value gets lost in the slop of 1 though. */
18864 static const USHORT content_v8u8[4][4] =
18866 {0x0000, 0x7f7f, 0x8880, 0x0000},
18867 {0x0080, 0x8000, 0x7f00, 0x007f},
18868 {0x193b, 0xe8c8, 0x0808, 0xf8f8},
18869 {0x4444, 0xc0c0, 0xa066, 0x22e0},
18871 static const DWORD content_v16u16[4][4] =
18873 {0x00000000, 0x7fff7fff, 0x88008000, 0x00000000},
18874 {0x00008000, 0x80000000, 0x7fff0000, 0x00007fff},
18875 {0x19993bbb, 0xe800c800, 0x08880888, 0xf800f800},
18876 {0x44444444, 0xc000c000, 0xa0006666, 0x2222e000},
18878 static const DWORD content_q8w8v8u8[4][4] =
18880 {0x00000000, 0xff7f7f7f, 0x7f008880, 0x817f0000},
18881 {0x10000080, 0x20008000, 0x30007f00, 0x4000007f},
18882 {0x5020193b, 0x6028e8c8, 0x70020808, 0x807ff8f8},
18883 {0x90414444, 0xa000c0c0, 0x8261a066, 0x834922e0},
18885 static const DWORD content_x8l8v8u8[4][4] =
18887 {0x00000000, 0x00ff7f7f, 0x00008880, 0x00ff0000},
18888 {0x00000080, 0x00008000, 0x00007f00, 0x0000007f},
18889 {0x0041193b, 0x0051e8c8, 0x00040808, 0x00fff8f8},
18890 {0x00824444, 0x0000c0c0, 0x00c2a066, 0x009222e0},
18892 /* D3DFMT_L6V5U5 has poor precision on some GPUs. On a GeForce 7 the highest V and U value (15)
18893 * results in the output color 0xfb, which is 4 steps away from the correct value 0xff. It is
18894 * not the ~0xf0 you'd get if you blindly left-shifted the 5 bit value to form an 8 bit value
18895 * though.
18897 * There may also be an off-by-one bug involved: The value -7 should result in the output 0x47,
18898 * but ends up as 0x4d. Likewise, -3 becomes 0x6e instead of 0x67. Those values are close to
18899 * the proper results of -6 and -2.
18901 * On Wine the emulation with unsigned R5G6B5 has poor precision, e.g. the signed 0 becomes 16,
18902 * and ((16 / 31) - 0.5) * 2.0 is 0.032 instead of 0.000. The final output result we read back
18903 * is 0x84 instead of 0x80. */
18904 static const USHORT content_l6v5u5[4][4] =
18906 {0x0000, 0xfdef, 0x0230, 0xfc00},
18907 {0x0010, 0x0200, 0x01e0, 0x000f},
18908 {0x4067, 0x53b9, 0x0421, 0xffff},
18909 {0x8108, 0x0318, 0xc28c, 0x909c},
18911 static const struct
18913 D3DFORMAT format;
18914 const char *name;
18915 const void *content;
18916 SIZE_T pixel_size;
18917 BOOL blue, alpha;
18918 unsigned int slop, slop_broken, alpha_broken;
18920 formats[] =
18922 {D3DFMT_V8U8, "D3DFMT_V8U8", content_v8u8, sizeof(WORD), FALSE, FALSE, 1, 0, FALSE},
18923 {D3DFMT_V16U16, "D3DFMT_V16U16", content_v16u16, sizeof(DWORD), FALSE, FALSE, 1, 0, FALSE},
18924 {D3DFMT_Q8W8V8U8, "D3DFMT_Q8W8V8U8", content_q8w8v8u8, sizeof(DWORD), TRUE, TRUE, 1, 0, TRUE },
18925 {D3DFMT_X8L8V8U8, "D3DFMT_X8L8V8U8", content_x8l8v8u8, sizeof(DWORD), TRUE, FALSE, 1, 0, FALSE},
18926 {D3DFMT_L6V5U5, "D3DFMT_L6V5U5", content_l6v5u5, sizeof(WORD), TRUE, FALSE, 4, 7, FALSE},
18928 static const struct
18930 D3DPOOL pool;
18931 UINT width;
18932 RECT src_rect;
18933 POINT dst_point;
18935 tests[] =
18937 {D3DPOOL_SYSTEMMEM, 4, {1, 1, 2, 3}, {2, 0}},
18938 {D3DPOOL_SYSTEMMEM, 1, {0, 1, 1, 3}, {0, 0}},
18939 {D3DPOOL_MANAGED, 4, {1, 1, 2, 3}, {2, 0}},
18940 {D3DPOOL_MANAGED, 1, {0, 1, 1, 3}, {0, 0}},
18942 static const DWORD shader_code[] =
18944 0xffff0101, /* ps_1_1 */
18945 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0,5, 0,5 */
18946 0x00000042, 0xb00f0000, /* tex t0 */
18947 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
18948 0x0000ffff /* end */
18950 static const DWORD shader_code_alpha[] =
18952 /* The idea of this shader is to replicate the alpha value in .rg, and set
18953 * blue to 1.0 iff the alpha value is < -1.0 and 0.0 otherwise. */
18954 0xffff0101, /* ps_1_1 */
18955 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
18956 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
18957 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
18958 0x00000042, 0xb00f0000, /* tex t0 */
18959 0x00000004, 0x80070000, 0xb0ff0000, 0xa0e40000, 0xa0e40000, /* mad r0.rgb, t0.a, c0, c0 */
18960 0x00000003, 0x80080000, 0xb1ff0000, 0xa0e40000, /* sub r0.a, -t0.a, c0 */
18961 0x00000050, 0x80080000, 0x80ff0000, 0xa0ff0001, 0xa0ff0002, /* cnd r0.a, r0.a, c1.a, c2.a */
18962 0x00000005, 0x80070001, 0xa0e40001, 0x80e40000, /* mul r1.rgb, c1, r0 */
18963 0x00000004, 0x80070000, 0x80ff0000, 0xa0e40002, 0x80e40001, /* mad r0.rgb, r0.a, c2, r1 */
18964 0x0000ffff /* end */
18966 static const struct
18968 struct vec3 position;
18969 struct vec2 texcrd;
18971 quad[] =
18973 /* Flip the y coordinate to make the input and
18974 * output arrays easier to compare. */
18975 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 1.0f}},
18976 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 0.0f}},
18977 {{ 1.0f, -1.0f, 0.0f}, { 1.0f, 1.0f}},
18978 {{ 1.0f, 1.0f, 0.0f}, { 1.0f, 0.0f}},
18980 static const D3DCOLOR expected_alpha[4][4] =
18982 {0x00808000, 0x007f7f00, 0x00ffff00, 0x00000000},
18983 {0x00909000, 0x00a0a000, 0x00b0b000, 0x00c0c000},
18984 {0x00d0d000, 0x00e0e000, 0x00f0f000, 0x00000000},
18985 {0x00101000, 0x00202000, 0x00010100, 0x00020200},
18987 static const BOOL alpha_broken[4][4] =
18989 {FALSE, FALSE, FALSE, FALSE},
18990 {FALSE, FALSE, FALSE, FALSE},
18991 {FALSE, FALSE, FALSE, TRUE },
18992 {FALSE, FALSE, FALSE, FALSE},
18994 static const D3DCOLOR expected_colors[4][4] =
18996 {0x00808080, 0x00fefeff, 0x00010780, 0x008080ff},
18997 {0x00018080, 0x00800180, 0x0080fe80, 0x00fe8080},
18998 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
18999 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
19001 static const D3DCOLOR expected_colors2[4][4] =
19003 {0x00808080, 0x00fefeff, 0x00800180, 0x008080ff},
19004 {0x00018080, 0x00800180, 0x004767a8, 0x00fe8080},
19005 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
19006 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
19008 static const D3DCOLOR expected_colors3[4] =
19010 0x00018080,
19011 0x00ba98a0,
19012 0x00ba98a0,
19013 0x00c3c3c0,
19015 D3DCOLOR expected_color;
19017 window = create_window();
19018 d3d = Direct3DCreate9(D3D_SDK_VERSION);
19019 ok(!!d3d, "Failed to create a D3D object.\n");
19021 if (!(device = create_device(d3d, window, window, TRUE)))
19023 skip("Failed to create a D3D device, skipping tests.\n");
19024 IDirect3D9_Release(d3d);
19025 DestroyWindow(window);
19026 return;
19029 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
19030 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
19032 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
19034 skip("Pixel shaders not supported, skipping converted format test.\n");
19035 goto done;
19038 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
19039 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19040 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
19041 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
19042 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
19043 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
19044 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_alpha, &shader_alpha);
19045 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
19047 for (i = 0; i < sizeof(formats) / sizeof(*formats); i++)
19049 hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
19050 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, formats[i].format);
19051 if (FAILED(hr))
19053 skip("Format %s not supported, skipping.\n", formats[i].name);
19054 continue;
19057 for (j = 0; j < sizeof(tests) / sizeof(*tests); j++)
19059 texture_sysmem = NULL;
19060 hr = IDirect3DDevice9_CreateTexture(device, tests[j].width, 4, 1, 0,
19061 formats[i].format, tests[j].pool, &texture, NULL);
19062 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
19064 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
19065 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
19066 for (y = 0; y < 4; y++)
19068 memcpy((char *)locked_rect.pBits + y * locked_rect.Pitch,
19069 (char *)formats[i].content + y * 4 * formats[i].pixel_size,
19070 tests[j].width * formats[i].pixel_size);
19072 hr = IDirect3DTexture9_UnlockRect(texture, 0);
19073 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
19075 if (tests[j].pool == D3DPOOL_SYSTEMMEM)
19077 texture_sysmem = texture;
19078 hr = IDirect3DDevice9_CreateTexture(device, tests[j].width, 4, 1, 0,
19079 formats[i].format, D3DPOOL_DEFAULT, &texture, NULL);
19080 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
19082 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture_sysmem,
19083 (IDirect3DBaseTexture9 *)texture);
19084 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
19087 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
19088 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
19089 hr = IDirect3DDevice9_SetPixelShader(device, shader_alpha);
19090 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
19092 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
19093 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19094 hr = IDirect3DDevice9_BeginScene(device);
19095 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19096 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
19097 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19098 hr = IDirect3DDevice9_EndScene(device);
19099 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19101 for (y = 0; y < 4; y++)
19103 for (x = 0; x < tests[j].width; x++)
19105 BOOL r200_broken = formats[i].alpha_broken && alpha_broken[y][x];
19106 if (formats[i].alpha)
19107 expected_color = expected_alpha[y][x];
19108 else
19109 expected_color = 0x00ffff00;
19111 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
19112 ok(color_match(color, expected_color, 1) || broken(r200_broken),
19113 "Expected color 0x%08x, got 0x%08x, format %s, test %u, location %ux%u.\n",
19114 expected_color, color, formats[i].name, j, x, y);
19117 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19118 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19120 hr = IDirect3DDevice9_SetPixelShader(device, shader);
19121 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
19123 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
19124 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19125 hr = IDirect3DDevice9_BeginScene(device);
19126 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19127 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
19128 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19129 hr = IDirect3DDevice9_EndScene(device);
19130 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19132 for (y = 0; y < 4; y++)
19134 for (x = 0; x < tests[j].width; x++)
19136 expected_color = expected_colors[y][x];
19137 if (!formats[i].blue)
19138 expected_color |= 0x000000ff;
19140 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
19141 ok(color_match(color, expected_color, formats[i].slop)
19142 || broken(color_match(color, expected_color, formats[i].slop_broken)),
19143 "Expected color 0x%08x, got 0x%08x, format %s, test %u, location %ux%u.\n",
19144 expected_color, color, formats[i].name, j, x, y);
19147 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19148 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19150 if (tests[j].pool != D3DPOOL_SYSTEMMEM)
19152 IDirect3DTexture9_Release(texture);
19153 continue;
19156 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &dst_surface);
19157 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x.\n", hr);
19158 IDirect3DTexture9_GetSurfaceLevel(texture_sysmem, 0, &src_surface);
19159 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x.\n", hr);
19161 hr = IDirect3DDevice9_UpdateSurface(device, src_surface,
19162 &tests[j].src_rect, dst_surface, &tests[j].dst_point);
19163 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
19165 IDirect3DSurface9_Release(dst_surface);
19166 IDirect3DSurface9_Release(src_surface);
19168 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00003300, 0.0f, 0);
19169 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19170 hr = IDirect3DDevice9_BeginScene(device);
19171 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19172 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
19173 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19174 hr = IDirect3DDevice9_EndScene(device);
19175 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19177 for (y = 0; y < 4; y++)
19179 for (x = 0; x < tests[j].width; x++)
19181 if (tests[j].width == 4)
19182 expected_color = expected_colors2[y][x];
19183 else
19184 expected_color = expected_colors3[y];
19186 if (!formats[i].blue)
19187 expected_color |= 0x000000ff;
19189 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
19190 ok(color_match(color, expected_color, formats[i].slop)
19191 || broken(color_match(color, expected_color, formats[i].slop_broken)),
19192 "Expected color 0x%08x, got 0x%08x, format %s, test %u, location %ux%u.\n",
19193 expected_color, color, formats[i].name, j, x, y);
19196 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19197 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19199 IDirect3DTexture9_Release(texture_sysmem);
19200 IDirect3DTexture9_Release(texture);
19204 IDirect3DPixelShader9_Release(shader);
19205 IDirect3DPixelShader9_Release(shader_alpha);
19207 done:
19208 refcount = IDirect3DDevice9_Release(device);
19209 ok(!refcount, "Device has %u references left.\n", refcount);
19210 IDirect3D9_Release(d3d);
19211 DestroyWindow(window);
19214 static void test_multisample_mismatch(void)
19216 IDirect3DDevice9 *device;
19217 IDirect3D9 *d3d;
19218 HWND window;
19219 HRESULT hr;
19220 D3DCOLOR color;
19221 ULONG refcount;
19222 IDirect3DSurface9 *rt, *rt_multi, *ds;
19223 static const struct
19225 struct vec3 position;
19226 DWORD color;
19228 quad[] =
19230 {{ -1.0f, -1.0f, 0.0f}, 0x000000ff},
19231 {{ -1.0f, 1.0f, 0.0f}, 0x000000ff},
19232 {{ 1.0f, -1.0f, 1.0f}, 0x000000ff},
19233 {{ 1.0f, 1.0f, 1.0f}, 0x000000ff},
19236 window = create_window();
19237 d3d = Direct3DCreate9(D3D_SDK_VERSION);
19238 ok(!!d3d, "Failed to create a D3D object.\n");
19239 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
19240 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
19242 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample mismatch test.\n");
19243 IDirect3D9_Release(d3d);
19244 return;
19246 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
19247 D3DFMT_D24X8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
19249 skip("Multisampling not supported for D3DFMT_D24X8, skipping multisample mismatch test.\n");
19250 IDirect3D9_Release(d3d);
19251 return;
19254 if (!(device = create_device(d3d, window, window, TRUE)))
19256 skip("Failed to create a D3D device, skipping tests.\n");
19257 IDirect3D9_Release(d3d);
19258 DestroyWindow(window);
19259 return;
19262 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
19263 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt_multi, NULL);
19264 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
19266 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.1f, 0);
19267 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19269 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
19270 ok(SUCCEEDED(hr), "Failed to set depth stencil, hr %#x.\n", hr);
19271 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
19272 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
19273 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
19274 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19276 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
19277 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19278 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
19279 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19281 /* Clear with incompatible buffers. Partial and combined clears. */
19282 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
19283 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19284 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.3f, 0);
19285 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19286 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 0.5f, 0);
19287 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19289 /* The color buffer is reliably cleared on AMD and Nvidia GPUs. */
19290 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
19291 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19292 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
19293 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
19294 color = getPixelColor(device, 320, 240);
19295 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
19296 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19297 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19299 /* Check depth buffer values. AMD GPUs (r500 and evergreen tested) clear the depth buffer
19300 * like you'd expect in a correct framebuffer setup. Nvidia doesn't clear it, neither in
19301 * the Z only clear case nor in the combined clear case. */
19302 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
19303 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
19304 hr = IDirect3DDevice9_BeginScene(device);
19305 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19306 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19307 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19308 hr = IDirect3DDevice9_EndScene(device);
19309 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19310 color = getPixelColor(device, 62, 240);
19311 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
19312 color = getPixelColor(device, 64, 240);
19313 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x000000ff, 1)),
19314 "Got unexpected color 0x%08x.\n", color);
19315 color = getPixelColor(device, 318, 240);
19316 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x000000ff, 1)),
19317 "Got unexpected color 0x%08x.\n", color);
19318 color = getPixelColor(device, 322, 240);
19319 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
19320 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19321 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19323 /* Draw with incompatible buffers. AMD even performs Z testing, and the Z test
19324 * results appear to be correct for this simple draw. Nvidia doesn't draw unless
19325 * the depth test is disabled. Setting ZFUNC = ALWAYS doesn't make the geometry
19326 * show up either. Only test the ZENABLE = FALSE case for now. */
19327 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
19328 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19329 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
19330 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19331 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
19332 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19333 hr = IDirect3DDevice9_BeginScene(device);
19334 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19335 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19336 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19337 hr = IDirect3DDevice9_EndScene(device);
19338 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19340 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
19341 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19342 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
19343 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
19344 color = getPixelColor(device, 320, 240);
19345 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
19346 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19347 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19349 IDirect3DSurface9_Release(ds);
19351 /* Test the reverse situation: Multisampled depth buffer, single sampled color buffer.
19352 * Color clears work as expected, AMD also clears the depth buffer, Nvidia does not. */
19353 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24X8,
19354 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
19355 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#x.\n", hr);
19356 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
19357 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
19358 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
19359 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19360 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ffff00, 0.1f, 0);
19361 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19363 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
19364 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19365 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
19366 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19367 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.3f, 0);
19368 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19369 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 0.5f, 0);
19370 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19372 color = getPixelColor(device, 320, 240);
19373 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
19374 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19375 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19377 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
19378 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19379 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
19380 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19381 hr = IDirect3DDevice9_BeginScene(device);
19382 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19383 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19384 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19385 hr = IDirect3DDevice9_EndScene(device);
19386 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19388 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
19389 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19390 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
19391 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
19392 color = getPixelColor(device, 62, 240);
19393 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
19394 color = getPixelColor(device, 318, 240);
19395 ok(color_match(color, 0x00ffff00, 1) || broken(color_match(color, 0x000000ff, 1)),
19396 "Got unexpected color 0x%08x.\n", color);
19397 color = getPixelColor(device, 322, 240);
19398 ok(color_match(color, 0x00ffff00, 1), "Got unexpected color 0x%08x.\n", color);
19399 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19400 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19402 /* Draw with a single sampled color buffer and a multisampled depth buffer. Again
19403 * AMD seems to perform correct Z testing, Nvidia doesn't draw unless the Z test
19404 * is disabled. Again only test the ZENABLE = FALSE case. */
19405 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
19406 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19407 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
19408 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19409 hr = IDirect3DDevice9_BeginScene(device);
19410 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19411 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19412 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19413 hr = IDirect3DDevice9_EndScene(device);
19414 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19415 color = getPixelColor(device, 320, 240);
19416 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
19417 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19418 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19420 IDirect3DSurface9_Release(rt);
19421 IDirect3DSurface9_Release(ds);
19422 IDirect3DSurface9_Release(rt_multi);
19424 refcount = IDirect3DDevice9_Release(device);
19425 ok(!refcount, "Device has %u references left.\n", refcount);
19426 IDirect3D9_Release(d3d);
19427 DestroyWindow(window);
19430 static void test_texcoordindex(void)
19432 static const D3DMATRIX mat =
19434 1.0f, 0.0f, 0.0f, 0.0f,
19435 0.0f, 0.0f, 0.0f, 0.0f,
19436 0.0f, 0.0f, 0.0f, 0.0f,
19437 0.0f, 0.0f, 0.0f, 0.0f,
19438 }}};
19439 static const struct
19441 struct vec3 pos;
19442 struct vec2 texcoord1;
19443 struct vec2 texcoord2;
19444 struct vec2 texcoord3;
19446 quad[] =
19448 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 1.0f}},
19449 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 0.0f}},
19450 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}, {1.0f, 0.0f}, {0.0f, 1.0f}},
19451 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 0.0f}},
19453 IDirect3DDevice9 *device;
19454 IDirect3D9 *d3d9;
19455 HWND window;
19456 HRESULT hr;
19457 IDirect3DTexture9 *texture1, *texture2;
19458 D3DLOCKED_RECT locked_rect;
19459 ULONG refcount;
19460 D3DCOLOR color;
19461 DWORD *ptr;
19463 window = create_window();
19464 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
19465 ok(!!d3d9, "Failed to create a D3D object.\n");
19466 if (!(device = create_device(d3d9, window, window, TRUE)))
19468 skip("Failed to create a D3D device, skipping tests.\n");
19469 IDirect3D9_Release(d3d9);
19470 DestroyWindow(window);
19471 return;
19474 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture1, NULL);
19475 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
19476 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
19477 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
19479 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
19480 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
19481 ptr = locked_rect.pBits;
19482 ptr[0] = 0xff000000;
19483 ptr[1] = 0xff00ff00;
19484 ptr[2] = 0xff0000ff;
19485 ptr[3] = 0xff00ffff;
19486 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
19487 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
19489 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
19490 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
19491 ptr = locked_rect.pBits;
19492 ptr[0] = 0xff000000;
19493 ptr[1] = 0xff0000ff;
19494 ptr[2] = 0xffff0000;
19495 ptr[3] = 0xffff00ff;
19496 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
19497 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
19499 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture1);
19500 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
19501 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *)texture2);
19502 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
19503 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX3);
19504 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
19505 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
19506 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
19507 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
19508 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
19509 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
19510 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
19511 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
19512 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
19513 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
19514 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
19515 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
19516 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
19517 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
19518 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
19520 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXCOORDINDEX, 1);
19521 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
19522 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 0);
19523 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
19525 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
19526 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19528 hr = IDirect3DDevice9_BeginScene(device);
19529 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19530 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19531 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19532 hr = IDirect3DDevice9_EndScene(device);
19533 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19535 color = getPixelColor(device, 160, 120);
19536 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
19537 color = getPixelColor(device, 480, 120);
19538 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19539 color = getPixelColor(device, 160, 360);
19540 ok(color_match(color, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color);
19541 color = getPixelColor(device, 480, 360);
19542 ok(color_match(color, 0x00ffffff, 2), "Got unexpected color 0x%08x.\n", color);
19544 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
19545 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
19546 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE1, &mat);
19547 ok(SUCCEEDED(hr), "Failed to set transformation matrix, hr %#x.\n", hr);
19549 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
19550 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19552 hr = IDirect3DDevice9_BeginScene(device);
19553 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19554 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19555 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19556 hr = IDirect3DDevice9_EndScene(device);
19557 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19559 color = getPixelColor(device, 160, 120);
19560 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
19561 color = getPixelColor(device, 480, 120);
19562 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19563 color = getPixelColor(device, 160, 360);
19564 ok(color_match(color, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color);
19565 color = getPixelColor(device, 480, 360);
19566 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19568 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
19569 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
19570 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 2);
19571 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
19573 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
19574 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19576 hr = IDirect3DDevice9_BeginScene(device);
19577 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19578 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19579 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19580 hr = IDirect3DDevice9_EndScene(device);
19581 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19583 color = getPixelColor(device, 160, 120);
19584 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
19585 color = getPixelColor(device, 480, 120);
19586 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19587 color = getPixelColor(device, 160, 360);
19588 ok(color_match(color, 0x00ff00ff, 2), "Got unexpected color 0x%08x.\n", color);
19589 color = getPixelColor(device, 480, 360);
19590 ok(color_match(color, 0x00ffff00, 2), "Got unexpected color 0x%08x.\n", color);
19592 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19593 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19595 IDirect3DTexture9_Release(texture1);
19596 IDirect3DTexture9_Release(texture2);
19598 refcount = IDirect3DDevice9_Release(device);
19599 ok(!refcount, "Device has %u references left.\n", refcount);
19600 IDirect3D9_Release(d3d9);
19601 DestroyWindow(window);
19604 static void test_vertex_blending(void)
19606 IDirect3DVertexDeclaration9 *vertex_declaration;
19607 IDirect3DDevice9 *device;
19608 IDirect3D9 *d3d;
19609 D3DCAPS9 caps;
19610 D3DCOLOR color;
19611 ULONG refcount;
19612 HWND window;
19613 HRESULT hr;
19614 int i;
19616 static const D3DMATRIX view_mat =
19618 2.0f / 10.0f, 0.0f, 0.0f, 0.0f,
19619 0.0f, 2.0f / 10.0f, 0.0f, 0.0f,
19620 0.0f, 0.0f, 1.0f, 0.0f,
19621 0.0f, 0.0f, 0.0f, 1.0f
19622 }}},
19623 upper_left =
19625 1.0f, 0.0f, 0.0f, 0.0f,
19626 0.0f, 1.0f, 0.0f, 0.0f,
19627 0.0f, 0.0f, 1.0f, 0.0f,
19628 -4.0f, 4.0f, 0.0f, 1.0f
19629 }}},
19630 lower_left =
19632 1.0f, 0.0f, 0.0f, 0.0f,
19633 0.0f, 1.0f, 0.0f, 0.0f,
19634 0.0f, 0.0f, 1.0f, 0.0f,
19635 -4.0f, -4.0f, 0.0f, 1.0f
19636 }}},
19637 upper_right =
19639 1.0f, 0.0f, 0.0f, 0.0f,
19640 0.0f, 1.0f, 0.0f, 0.0f,
19641 0.0f, 0.0f, 1.0f, 0.0f,
19642 4.0f, 4.0f, 0.0f, 1.0f
19643 }}},
19644 lower_right =
19646 1.0f, 0.0f, 0.0f, 0.0f,
19647 0.0f, 1.0f, 0.0f, 0.0f,
19648 0.0f, 0.0f, 1.0f, 0.0f,
19649 4.0f, -4.0f, 0.0f, 1.0f
19650 }}};
19652 static const POINT quad_upper_right_points[] =
19654 {576, 48}, {-1, -1},
19656 quad_upper_right_empty_points[] =
19658 {64, 48}, {64, 432}, {576, 432}, {320, 240}, {-1, -1}
19660 quad_center_points[] =
19662 {320, 240}, {-1, -1}
19664 quad_center_empty_points[] =
19666 {64, 48}, {576, 48}, {64, 432}, {576, 432}, {-1, -1}
19668 quad_upper_center_points[] =
19670 {320, 48}, {-1, -1}
19672 quad_upper_center_empty_points[] =
19674 {320, 240}, {64, 48}, {576, 48}, {-1, -1}
19676 quad_fullscreen_points[] =
19678 {320, 48}, {320, 240}, {64, 48}, {576, 48}, {64, 432}, {576, 432}, {-1, -1}
19680 quad_fullscreen_empty_points[] =
19682 {-1, -1}
19685 static const struct
19687 DWORD fvf;
19688 D3DVERTEXELEMENT9 decl_elements[3];
19689 struct
19691 struct
19693 struct vec3 position;
19694 struct vec3 blendweights;
19696 vertex_data_float[4];
19697 struct
19699 struct vec3 position;
19700 D3DCOLOR blendweights;
19702 vertex_data_d3dcolor[4];
19703 } s;
19704 const POINT *quad_points;
19705 const POINT *empty_points;
19707 tests[] =
19709 /* upper right */
19711 D3DFVF_XYZB3,
19712 {{0}},
19713 {{{{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
19714 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
19715 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
19716 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}}}},
19717 quad_upper_right_points, quad_upper_right_empty_points
19719 /* center */
19721 D3DFVF_XYZB3,
19722 {{0}},
19723 {{{{-1.0f, -1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}},
19724 {{-1.0f, 1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}},
19725 {{ 1.0f, -1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}},
19726 {{ 1.0f, 1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}}}},
19727 quad_center_points, quad_center_empty_points
19729 /* upper center */
19731 D3DFVF_XYZB3,
19732 {{0}},
19733 {{{{-1.0f, -1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}},
19734 {{-1.0f, 1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}},
19735 {{ 1.0f, -1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}},
19736 {{ 1.0f, 1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}}}},
19737 quad_upper_center_points, quad_upper_center_empty_points
19739 /* full screen */
19741 D3DFVF_XYZB3,
19742 {{0}},
19743 {{{{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}},
19744 {{-1.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}},
19745 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}},
19746 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}}}},
19747 quad_fullscreen_points, quad_fullscreen_empty_points
19749 /* D3DCOLOR, full screen */
19753 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
19754 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
19755 D3DDECL_END()
19757 {{{{0}}},
19758 {{{-1.0f, -1.0f, 0.0f}, 0x0000ff00},
19759 {{-1.0f, 1.0f, 0.0f}, 0x00ff0000},
19760 {{ 1.0f, -1.0f, 0.0f}, 0x000000ff},
19761 {{ 1.0f, 1.0f, 0.0f}, 0x00000000}}},
19762 quad_fullscreen_points, quad_fullscreen_empty_points
19766 window = create_window();
19767 d3d = Direct3DCreate9(D3D_SDK_VERSION);
19768 ok(!!d3d, "Failed to create a D3D object.\n");
19769 if (!(device = create_device(d3d, window, window, TRUE)))
19771 skip("Failed to create a D3D device, skipping tests.\n");
19772 goto done;
19775 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
19776 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
19777 if (caps.MaxVertexBlendMatrices < 4)
19779 skip("Only %u vertex blend matrices supported, skipping tests.\n", caps.MaxVertexBlendMatrices);
19780 IDirect3DDevice9_Release(device);
19781 goto done;
19784 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
19785 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
19787 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &view_mat);
19788 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19790 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &upper_left);
19791 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19792 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(1), &lower_left);
19793 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19794 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(2), &lower_right);
19795 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19796 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(3), &upper_right);
19797 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19799 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_VERTEXBLEND, D3DVBF_3WEIGHTS);
19800 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed %08x\n", hr);
19802 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
19804 const POINT *point;
19806 if (tests[i].fvf)
19808 hr = IDirect3DDevice9_SetFVF(device, tests[i].fvf);
19809 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
19810 vertex_declaration = NULL;
19812 else
19814 hr = IDirect3DDevice9_CreateVertexDeclaration(device, tests[i].decl_elements, &vertex_declaration);
19815 ok(SUCCEEDED(hr), "Failed to create vertex declaration, hr %#x.\n", hr);
19816 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
19817 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
19820 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
19821 ok(SUCCEEDED(hr), "Failed to clear %08x\n", hr);
19823 hr = IDirect3DDevice9_BeginScene(device);
19824 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19826 if (tests[i].fvf)
19827 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
19828 tests[i].s.vertex_data_float, sizeof(*tests[i].s.vertex_data_float));
19829 else
19830 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
19831 tests[i].s.vertex_data_d3dcolor, sizeof(*tests[i].s.vertex_data_d3dcolor));
19832 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19834 hr = IDirect3DDevice9_EndScene(device);
19835 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19837 point = tests[i].quad_points;
19838 while (point->x != -1 && point->y != -1)
19840 color = getPixelColor(device, point->x, point->y);
19841 ok(color_match(color, 0x00ffffff, 1), "Expected quad at %dx%d.\n", point->x, point->y);
19842 ++point;
19845 point = tests[i].empty_points;
19846 while (point->x != -1 && point->y != -1)
19848 color = getPixelColor(device, point->x, point->y);
19849 ok(color_match(color, 0x00000000, 1), "Unexpected quad at %dx%d.\n", point->x, point->y);
19850 ++point;
19853 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19854 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19856 if (vertex_declaration)
19857 IDirect3DVertexDeclaration9_Release(vertex_declaration);
19860 refcount = IDirect3DDevice9_Release(device);
19861 ok(!refcount, "Device has %u references left.\n", refcount);
19863 done:
19864 IDirect3D9_Release(d3d);
19865 DestroyWindow(window);
19868 static void test_updatetexture(void)
19870 BOOL r32f_supported, ati2n_supported, do_visual_test;
19871 IDirect3DBaseTexture9 *src, *dst;
19872 unsigned int t, i, f, l, x, y, z;
19873 D3DLOCKED_RECT locked_rect;
19874 D3DLOCKED_BOX locked_box;
19875 IDirect3DDevice9 *device;
19876 IDirect3D9 *d3d9;
19877 ULONG refcount;
19878 D3DCOLOR color;
19879 D3DCAPS9 caps;
19880 HWND window;
19881 HRESULT hr;
19882 static const struct
19884 struct vec3 pos;
19885 struct vec2 texcoord;
19887 quad[] =
19889 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}},
19890 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}},
19891 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}},
19892 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
19894 static const struct
19896 struct vec3 pos;
19897 struct vec3 texcoord;
19899 quad_cube_tex[] =
19901 {{-1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, 0.5f}},
19902 {{-1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, 0.5f}},
19903 {{ 1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, -0.5f}},
19904 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, -0.5f}},
19906 static const struct
19908 UINT src_width, src_height;
19909 UINT dst_width, dst_height;
19910 UINT src_levels, dst_levels;
19911 D3DFORMAT src_format, dst_format;
19912 BOOL broken;
19914 tests[] =
19916 {8, 8, 8, 8, 0, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 0 */
19917 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 1 */
19918 {8, 8, 8, 8, 2, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 2 */
19919 {8, 8, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 3 */
19920 {8, 8, 8, 8, 4, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 4 */
19921 {8, 8, 2, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 5 */
19922 /* The WARP renderer doesn't handle these cases correctly. */
19923 {8, 8, 8, 8, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 6 */
19924 {8, 8, 4, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 7 */
19925 /* Not clear what happens here on Windows, it doesn't make much sense
19926 * though (on Nvidia it seems to upload the 4x4 surface into the 7x7
19927 * one or something like that). */
19928 /* {8, 8, 7, 7, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
19929 {8, 8, 8, 8, 1, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 8 */
19930 {4, 4, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 9 */
19931 /* This one causes weird behavior on Windows (it probably writes out
19932 * of the texture memory). */
19933 /* {8, 8, 4, 4, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
19934 {8, 4, 4, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 10 */
19935 {8, 4, 2, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 11 */
19936 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8, FALSE}, /* 12 */
19937 {8, 8, 8, 8, 4, 4, D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 13 */
19938 /* The data is converted correctly on AMD, on Nvidia nothing happens
19939 * (it draws a black quad). */
19940 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_R5G6B5, TRUE}, /* 14 */
19941 /* Here the data is converted on AMD, just copied and "reinterpreted" as
19942 * a 32 bit float on Nvidia (specifically the tested value becomes a
19943 * very small float number which we get as 0 in the test). */
19944 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_R32F, TRUE}, /* 15 */
19945 /* This one doesn't seem to give the expected results on AMD. */
19946 /* {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_Q8W8V8U8, FALSE}, */
19947 {8, 8, 8, 8, 4, 4, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 16 */
19948 {8, 8, 8, 8, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 17 */
19949 {8, 8, 2, 2, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 18 */
19951 static const struct
19953 D3DRESOURCETYPE type;
19954 DWORD fvf;
19955 const void *quad;
19956 unsigned int vertex_size;
19957 DWORD cap;
19958 const char *name;
19960 texture_types[] =
19962 {D3DRTYPE_TEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
19963 quad, sizeof(*quad), D3DPTEXTURECAPS_MIPMAP, "2D mipmapped"},
19965 {D3DRTYPE_CUBETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0),
19966 quad_cube_tex, sizeof(*quad_cube_tex), D3DPTEXTURECAPS_CUBEMAP, "Cube"},
19968 {D3DRTYPE_VOLUMETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
19969 quad, sizeof(*quad), D3DPTEXTURECAPS_VOLUMEMAP, "Volume"}
19972 window = create_window();
19973 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
19974 ok(!!d3d9, "Failed to create a D3D object.\n");
19975 if (!(device = create_device(d3d9, window, window, TRUE)))
19977 skip("Failed to create a D3D device, skipping tests.\n");
19978 IDirect3D9_Release(d3d9);
19979 DestroyWindow(window);
19980 return;
19983 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
19984 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
19986 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
19987 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#x.\n", hr);
19988 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
19989 ok(SUCCEEDED(hr), "Failed to set texture clamping state, hr %#x.\n", hr);
19990 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
19991 ok(SUCCEEDED(hr), "Failed to set texture clamping state, hr %#x.\n", hr);
19992 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
19993 ok(SUCCEEDED(hr), "Failed to set texture clamping state, hr %#x.\n", hr);
19994 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
19995 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19996 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
19997 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#x.\n", hr);
19998 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
19999 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#x.\n", hr);
20001 for (t = 0; t < sizeof(texture_types) / sizeof(*texture_types); ++t)
20003 if (!(caps.TextureCaps & texture_types[t].cap))
20005 skip("%s textures not supported, skipping some tests.\n", texture_types[t].name);
20006 continue;
20008 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20009 D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_FILTER, texture_types[t].type, D3DFMT_A8R8G8B8)))
20011 skip("%s D3DFMT_A8R8G8B8 texture filtering is not supported, skipping some tests.\n",
20012 texture_types[t].name);
20013 continue;
20015 r32f_supported = TRUE;
20016 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20017 D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_FILTER, texture_types[t].type, D3DFMT_R32F)))
20019 skip("%s R32F textures are not supported, skipping some tests.\n", texture_types[t].name);
20020 r32f_supported = FALSE;
20022 ati2n_supported = TRUE;
20023 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20024 D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_FILTER, texture_types[t].type, MAKEFOURCC('A','T','I','2'))))
20026 skip("%s ATI2N textures are not supported, skipping some tests.\n", texture_types[t].name);
20027 ati2n_supported = FALSE;
20030 hr = IDirect3DDevice9_SetFVF(device, texture_types[t].fvf);
20031 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
20033 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
20035 if (tests[i].dst_format == D3DFMT_R32F && !r32f_supported)
20036 continue;
20037 if (tests[i].dst_format == MAKEFOURCC('A','T','I','2') && !ati2n_supported)
20038 continue;
20040 switch (texture_types[t].type)
20042 case D3DRTYPE_TEXTURE:
20043 hr = IDirect3DDevice9_CreateTexture(device,
20044 tests[i].src_width, tests[i].src_height,
20045 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
20046 (IDirect3DTexture9 **)&src, NULL);
20047 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
20048 hr = IDirect3DDevice9_CreateTexture(device,
20049 tests[i].dst_width, tests[i].dst_height,
20050 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
20051 (IDirect3DTexture9 **)&dst, NULL);
20052 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
20053 break;
20054 case D3DRTYPE_CUBETEXTURE:
20055 hr = IDirect3DDevice9_CreateCubeTexture(device,
20056 tests[i].src_width,
20057 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
20058 (IDirect3DCubeTexture9 **)&src, NULL);
20059 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
20060 hr = IDirect3DDevice9_CreateCubeTexture(device,
20061 tests[i].dst_width,
20062 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
20063 (IDirect3DCubeTexture9 **)&dst, NULL);
20064 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
20065 break;
20066 case D3DRTYPE_VOLUMETEXTURE:
20067 hr = IDirect3DDevice9_CreateVolumeTexture(device,
20068 tests[i].src_width, tests[i].src_height, tests[i].src_width,
20069 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
20070 (IDirect3DVolumeTexture9 **)&src, NULL);
20071 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
20072 hr = IDirect3DDevice9_CreateVolumeTexture(device,
20073 tests[i].dst_width, tests[i].dst_height, tests[i].dst_width,
20074 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
20075 (IDirect3DVolumeTexture9 **)&dst, NULL);
20076 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
20077 break;
20078 default:
20079 trace("Unexpected resource type.\n");
20082 /* Skip the visual part of the test for ATI2N (laziness) and cases that
20083 * give a different (and unlikely to be useful) result. */
20084 do_visual_test = (tests[i].src_format == D3DFMT_A8R8G8B8 || tests[i].src_format == D3DFMT_X8R8G8B8)
20085 && tests[i].src_levels != 0
20086 && tests[i].src_width >= tests[i].dst_width && tests[i].src_height >= tests[i].dst_height
20087 && !(tests[i].src_width > tests[i].src_height && tests[i].dst_width < tests[i].dst_height);
20089 if (do_visual_test)
20091 DWORD *ptr = NULL;
20092 unsigned int width, height, depth, row_pitch = 0, slice_pitch = 0;
20094 for (f = 0; f < (texture_types[t].type == D3DRTYPE_CUBETEXTURE ? 6 : 1); ++f)
20096 width = tests[i].src_width;
20097 height = texture_types[t].type != D3DRTYPE_CUBETEXTURE ? tests[i].src_height : tests[i].src_width;
20098 depth = texture_types[t].type == D3DRTYPE_VOLUMETEXTURE ? width : 1;
20100 for (l = 0; l < tests[i].src_levels; ++l)
20102 switch (texture_types[t].type)
20104 case D3DRTYPE_TEXTURE:
20105 hr = IDirect3DTexture9_LockRect((IDirect3DTexture9 *)src,
20106 l, &locked_rect, NULL, 0);
20107 ptr = locked_rect.pBits;
20108 row_pitch = locked_rect.Pitch / sizeof(*ptr);
20109 break;
20110 case D3DRTYPE_CUBETEXTURE:
20111 hr = IDirect3DCubeTexture9_LockRect((IDirect3DCubeTexture9 *)src,
20112 f, l, &locked_rect, NULL, 0);
20113 ptr = locked_rect.pBits;
20114 row_pitch = locked_rect.Pitch / sizeof(*ptr);
20115 break;
20116 case D3DRTYPE_VOLUMETEXTURE:
20117 hr = IDirect3DVolumeTexture9_LockBox((IDirect3DVolumeTexture9 *)src,
20118 l, &locked_box, NULL, 0);
20119 ptr = locked_box.pBits;
20120 row_pitch = locked_box.RowPitch / sizeof(*ptr);
20121 slice_pitch = locked_box.SlicePitch / sizeof(*ptr);
20122 break;
20123 default:
20124 trace("Unexpected resource type.\n");
20126 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
20128 for (z = 0; z < depth; ++z)
20130 for (y = 0; y < height; ++y)
20132 for (x = 0; x < width; ++x)
20134 ptr[z * slice_pitch + y * row_pitch + x] = 0xff000000
20135 | (DWORD)(x / (width - 1.0f) * 255.0f) << 16
20136 | (DWORD)(y / (height - 1.0f) * 255.0f) << 8;
20141 switch (texture_types[t].type)
20143 case D3DRTYPE_TEXTURE:
20144 hr = IDirect3DTexture9_UnlockRect((IDirect3DTexture9 *)src, l);
20145 break;
20146 case D3DRTYPE_CUBETEXTURE:
20147 hr = IDirect3DCubeTexture9_UnlockRect((IDirect3DCubeTexture9 *)src, f, l);
20148 break;
20149 case D3DRTYPE_VOLUMETEXTURE:
20150 hr = IDirect3DVolumeTexture9_UnlockBox((IDirect3DVolumeTexture9 *)src, l);
20151 break;
20152 default:
20153 trace("Unexpected resource type.\n");
20155 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
20157 width >>= 1;
20158 if (!width)
20159 width = 1;
20160 height >>= 1;
20161 if (!height)
20162 height = 1;
20163 depth >>= 1;
20164 if (!depth)
20165 depth = 1;
20170 hr = IDirect3DDevice9_UpdateTexture(device, src, dst);
20171 if (FAILED(hr))
20173 todo_wine ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u, %u.\n", hr, t, i);
20174 IDirect3DBaseTexture9_Release(src);
20175 IDirect3DBaseTexture9_Release(dst);
20176 continue;
20178 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u, %u.\n", hr, t, i);
20180 if (do_visual_test)
20182 hr = IDirect3DDevice9_SetTexture(device, 0, dst);
20183 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
20185 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 1.0f, 0);
20186 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
20188 hr = IDirect3DDevice9_BeginScene(device);
20189 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
20190 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
20191 texture_types[t].quad, texture_types[t].vertex_size);
20192 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20193 hr = IDirect3DDevice9_EndScene(device);
20194 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
20196 color = getPixelColor(device, 320, 240);
20197 ok (color_match(color, 0x007f7f00, 3) || broken(tests[i].broken)
20198 || broken(color == 0x00adbeef), /* WARP device often just breaks down. */
20199 "Got unexpected color 0x%08x, case %u, %u.\n", color, t, i);
20202 IDirect3DBaseTexture9_Release(src);
20203 IDirect3DBaseTexture9_Release(dst);
20206 refcount = IDirect3DDevice9_Release(device);
20207 ok(!refcount, "Device has %u references left.\n", refcount);
20208 IDirect3D9_Release(d3d9);
20209 DestroyWindow(window);
20212 static void test_depthbias(void)
20214 IDirect3DDevice9 *device;
20215 IDirect3D9 *d3d;
20216 IDirect3DSurface9 *ds;
20217 D3DCAPS9 caps;
20218 D3DCOLOR color;
20219 ULONG refcount;
20220 HWND window;
20221 HRESULT hr;
20222 unsigned int i;
20223 static const D3DFORMAT formats[] =
20225 D3DFMT_D16, D3DFMT_D24X8, D3DFMT_D32, D3DFMT_D24S8, MAKEFOURCC('I','N','T','Z'),
20227 /* The scaling factor detection function detects the wrong factor for
20228 * float formats on Nvidia, therefore the following tests are disabled.
20229 * The wined3d function detects 2^23 like for fixed point formats but
20230 * the test needs 2^22 to pass.
20232 * AMD GPUs need a different scaling factor for float depth buffers
20233 * (2^24) than fixed point (2^23), but the wined3d detection function
20234 * works there, producing the right result in the test.
20236 * D3DFMT_D32F_LOCKABLE, D3DFMT_D24FS8,
20240 static const struct
20242 struct vec3 position;
20244 quad[] =
20246 {{-1.0f, -1.0f, 0.0f}},
20247 {{-1.0f, 1.0f, 0.0f}},
20248 {{ 1.0f, -1.0f, 1.0f}},
20249 {{ 1.0f, 1.0f, 1.0f}},
20251 union
20253 float f;
20254 DWORD d;
20255 } conv;
20257 window = create_window();
20258 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20259 ok(!!d3d, "Failed to create a D3D object.\n");
20260 if (!(device = create_device(d3d, window, window, TRUE)))
20262 skip("Failed to create a D3D device, skipping tests.\n");
20263 goto done;
20266 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
20267 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
20268 if (!(caps.RasterCaps & D3DPRASTERCAPS_DEPTHBIAS))
20270 IDirect3DDevice9_Release(device);
20271 skip("D3DPRASTERCAPS_DEPTHBIAS not supported.\n");
20272 goto done;
20275 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
20276 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
20277 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
20278 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
20279 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
20280 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
20281 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
20282 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
20283 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
20284 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
20286 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
20288 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20289 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, formats[i])))
20291 skip("Depth format %u not supported, skipping.\n", formats[i]);
20292 continue;
20295 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, formats[i],
20296 D3DMULTISAMPLE_NONE, 0, FALSE, &ds, NULL);
20297 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
20298 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
20299 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
20300 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 0.5f, 0);
20301 ok(SUCCEEDED(hr), "Failed to clear %08x\n", hr);
20303 hr = IDirect3DDevice9_BeginScene(device);
20304 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
20306 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x00ff0000);
20307 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20308 conv.f = -0.2f;
20309 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
20310 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20311 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20312 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20314 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
20315 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20316 conv.f = 0.0f;
20317 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
20318 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20319 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20320 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20322 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x000000ff);
20323 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20324 conv.f = 0.2f;
20325 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
20326 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20327 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20328 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20330 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x00ffffff);
20331 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20332 conv.f = 0.4f;
20333 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
20334 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20335 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20336 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20338 color = getPixelColor(device, 61, 240);
20339 ok(color_match(color, 0x00ffffff, 1), "Got unexpected color %08x at x=62, format %u.\n", color, formats[i]);
20340 color = getPixelColor(device, 65, 240);
20342 /* The broken results are for the WARP driver on the testbot. It seems to initialize
20343 * a scaling factor based on the first depth format that is used. Other formats with
20344 * a different depth size then render incorrectly. */
20345 ok(color_match(color, 0x000000ff, 1) || broken(color_match(color, 0x00ffffff, 1)),
20346 "Got unexpected color %08x at x=64, format %u.\n", color, formats[i]);
20347 color = getPixelColor(device, 190, 240);
20348 ok(color_match(color, 0x000000ff, 1) || broken(color_match(color, 0x00ffffff, 1)),
20349 "Got unexpected color %08x at x=190, format %u.\n", color, formats[i]);
20351 color = getPixelColor(device, 194, 240);
20352 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ffffff, 1)),
20353 "Got unexpected color %08x at x=194, format %u.\n", color, formats[i]);
20354 color = getPixelColor(device, 318, 240);
20355 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ffffff, 1)),
20356 "Got unexpected color %08x at x=318, format %u.\n", color, formats[i]);
20358 color = getPixelColor(device, 322, 240);
20359 ok(color_match(color, 0x00ff0000, 1) || broken(color_match(color, 0x00000000, 1)),
20360 "Got unexpected color %08x at x=322, format %u.\n", color, formats[i]);
20361 color = getPixelColor(device, 446, 240);
20362 ok(color_match(color, 0x00ff0000, 1) || broken(color_match(color, 0x00000000, 1)),
20363 "Got unexpected color %08x at x=446, format %u.\n", color, formats[i]);
20365 color = getPixelColor(device, 450, 240);
20366 ok(color_match(color, 0x00000000, 1), "Got unexpected color %08x at x=446, format %u.\n", color, formats[i]);
20368 hr = IDirect3DDevice9_EndScene(device);
20369 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
20371 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20372 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
20373 IDirect3DSurface9_Release(ds);
20376 refcount = IDirect3DDevice9_Release(device);
20377 ok(!refcount, "Device has %u references left.\n", refcount);
20379 done:
20380 IDirect3D9_Release(d3d);
20381 DestroyWindow(window);
20384 static void test_flip(void)
20386 IDirect3DDevice9 *device;
20387 IDirect3D9 *d3d;
20388 ULONG refcount;
20389 HWND window;
20390 HRESULT hr;
20391 IDirect3DSurface9 *back_buffers[3], *test_surface;
20392 unsigned int i;
20393 D3DCOLOR color;
20394 D3DPRESENT_PARAMETERS present_parameters = {0};
20396 window = create_window();
20397 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20398 ok(!!d3d, "Failed to create a D3D object.\n");
20400 present_parameters.BackBufferWidth = 640;
20401 present_parameters.BackBufferHeight = 480;
20402 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
20403 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
20404 present_parameters.hDeviceWindow = window;
20405 present_parameters.Windowed = TRUE;
20406 present_parameters.BackBufferCount = 3;
20407 present_parameters.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
20408 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20409 window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
20410 if (!device)
20412 skip("Failed to create a D3D device, skipping tests.\n");
20413 IDirect3D9_Release(d3d);
20414 DestroyWindow(window);
20415 return;
20418 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
20420 hr = IDirect3DDevice9_GetBackBuffer(device, 0, i, D3DBACKBUFFER_TYPE_MONO, &back_buffers[i]);
20421 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
20423 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &test_surface);
20424 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
20425 ok(test_surface == back_buffers[0], "Expected render target %p, got %p.\n", back_buffers[0], test_surface);
20426 IDirect3DSurface9_Release(test_surface);
20428 hr = IDirect3DDevice9_SetRenderTarget(device, 0, back_buffers[2]);
20429 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
20431 hr = IDirect3DDevice9_ColorFill(device, back_buffers[0], NULL, 0xffff0000);
20432 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x.\n", hr);
20433 hr = IDirect3DDevice9_ColorFill(device, back_buffers[1], NULL, 0xff00ff00);
20434 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x.\n", hr);
20435 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
20436 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
20438 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20439 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20441 /* Render target is unmodified. */
20442 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &test_surface);
20443 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
20444 ok(test_surface == back_buffers[2], "Expected render target %p, got %p.\n", back_buffers[2], test_surface);
20445 IDirect3DSurface9_Release(test_surface);
20447 /* Backbuffer surface pointers are unmodified */
20448 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
20450 hr = IDirect3DDevice9_GetBackBuffer(device, 0, i, D3DBACKBUFFER_TYPE_MONO, &test_surface);
20451 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
20452 ok(test_surface == back_buffers[i], "Expected back buffer %u = %p, got %p.\n",
20453 i, back_buffers[i], test_surface);
20454 IDirect3DSurface9_Release(test_surface);
20457 /* Contents were changed. */
20458 color = getPixelColorFromSurface(back_buffers[0], 1, 1);
20459 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
20460 color = getPixelColorFromSurface(back_buffers[1], 1, 1);
20461 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
20463 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0f, 0);
20464 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
20466 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20467 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20469 color = getPixelColorFromSurface(back_buffers[0], 1, 1);
20470 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
20471 color = getPixelColorFromSurface(back_buffers[1], 1, 1);
20472 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
20474 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20475 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20477 color = getPixelColorFromSurface(back_buffers[0], 1, 1);
20478 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
20480 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
20481 IDirect3DSurface9_Release(back_buffers[i]);
20483 refcount = IDirect3DDevice9_Release(device);
20484 ok(!refcount, "Device has %u references left.\n", refcount);
20486 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20487 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
20489 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample flip test.\n");
20490 goto done;
20493 present_parameters.BackBufferCount = 2;
20494 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
20495 present_parameters.Flags = 0;
20496 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20497 window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
20499 for (i = 0; i < present_parameters.BackBufferCount; ++i)
20501 hr = IDirect3DDevice9_GetBackBuffer(device, 0, i, D3DBACKBUFFER_TYPE_MONO, &back_buffers[i]);
20502 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
20505 hr = IDirect3DDevice9_SetRenderTarget(device, 0, back_buffers[1]);
20506 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
20507 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0f, 0);
20508 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
20510 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20511 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20513 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
20514 D3DMULTISAMPLE_NONE, 0, TRUE, &test_surface, NULL);
20515 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
20516 hr = IDirect3DDevice9_StretchRect(device, back_buffers[0], NULL, test_surface, NULL, D3DTEXF_POINT);
20517 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
20519 color = getPixelColorFromSurface(test_surface, 1, 1);
20520 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
20522 IDirect3DSurface9_Release(test_surface);
20523 for (i = 0; i < present_parameters.BackBufferCount; ++i)
20524 IDirect3DSurface9_Release(back_buffers[i]);
20526 refcount = IDirect3DDevice9_Release(device);
20527 ok(!refcount, "Device has %u references left.\n", refcount);
20529 done:
20530 IDirect3D9_Release(d3d);
20531 DestroyWindow(window);
20534 static void test_uninitialized_varyings(void)
20536 static const D3DMATRIX mat =
20538 1.0f, 0.0f, 0.0f, 0.0f,
20539 0.0f, 1.0f, 0.0f, 0.0f,
20540 0.0f, 0.0f, 1.0f, 0.0f,
20541 0.0f, 0.0f, 0.0f, 1.0f,
20542 }}};
20543 static const struct vec3 quad[] =
20545 {-1.0f, -1.0f, 0.1f},
20546 {-1.0f, 1.0f, 0.1f},
20547 { 1.0f, -1.0f, 0.1f},
20548 { 1.0f, 1.0f, 0.1f},
20550 static const DWORD vs1_code[] =
20552 0xfffe0101, /* vs_1_1 */
20553 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20554 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
20555 0x0000ffff
20557 static const DWORD vs1_partial_code[] =
20559 0xfffe0101, /* vs_1_1 */
20560 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20561 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
20562 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
20563 0x00000001, 0xd0010000, 0xa0e40000, /* mov oD0.x, c0 */
20564 0x00000001, 0xd0010001, 0xa0e40000, /* mov oD1.x, c0 */
20565 0x00000001, 0xe0010000, 0xa0e40000, /* mov oT0.x, c0 */
20566 0x0000ffff
20568 static const DWORD vs2_code[] =
20570 0xfffe0200, /* vs_2_0 */
20571 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20572 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
20573 0x0000ffff
20575 static const DWORD vs2_partial_code[] =
20577 0xfffe0200, /* vs_2_0 */
20578 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20579 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
20580 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
20581 0x02000001, 0xd0010000, 0xa0e40000, /* mov oD0.x, c0 */
20582 0x02000001, 0xd0010001, 0xa0e40000, /* mov oD1.x, c0 */
20583 0x02000001, 0xe0010000, 0xa0e40000, /* mov oT0.x, c0 */
20584 0x0000ffff
20586 static const DWORD vs3_code[] =
20588 0xfffe0300, /* vs_3_0 */
20589 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20590 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
20591 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
20592 0x0000ffff
20594 static const DWORD vs3_partial_code[] =
20596 0xfffe0300, /* vs_3_0 */
20597 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20598 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
20599 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
20600 0x0200001f, 0x8001000a, 0xe00f0002, /* dcl_color1 o2 */
20601 0x0200001f, 0x80000005, 0xe00f0003, /* dcl_texcoord0 o3 */
20602 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
20603 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
20604 0x02000001, 0xe0010001, 0xa0e40000, /* mov o1.x, c0 */
20605 0x02000001, 0xe0010002, 0xa0e40000, /* mov o2.x, c0 */
20606 0x02000001, 0xe0010003, 0xa0e40000, /* mov o3.x, c0 */
20607 0x0000ffff
20609 static const DWORD ps1_diffuse_code[] =
20611 0xffff0101, /* ps_1_1 */
20612 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
20613 0x0000ffff
20615 static const DWORD ps1_specular_code[] =
20617 0xffff0101, /* ps_1_1 */
20618 0x00000001, 0x800f0000, 0x90e40001, /* mov r0, v1 */
20619 0x0000ffff
20621 static const DWORD ps1_texcoord_code[] =
20623 0xffff0101, /* ps_1_1 */
20624 0x00000040, 0xb00f0000, /* texcoord t0 */
20625 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
20626 0x0000ffff
20628 static const DWORD ps2_diffuse_code[] =
20630 0xffff0200, /* ps_2_0 */
20631 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
20632 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
20633 0x0000ffff
20635 static const DWORD ps2_specular_code[] =
20637 0xffff0200, /* ps_2_0 */
20638 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
20639 0x02000001, 0x800f0800, 0x90e40001, /* mov oC0, v1 */
20640 0x0000ffff
20642 static const DWORD ps2_texcoord_code[] =
20644 0xffff0200, /* ps_2_0 */
20645 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
20646 0x02000001, 0x800f0800, 0xb0e40000, /* mov oC0, t0 */
20647 0x0000ffff
20649 #if 0
20650 /* This has been left here for documentation purposes. It is referenced in disabled tests in the table below. */
20651 static const DWORD ps3_diffuse_code[] =
20653 0xffff0300, /* ps_3_0 */
20654 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
20655 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
20656 0x0000ffff
20658 #endif
20659 static const DWORD ps3_specular_code[] =
20661 0xffff0300, /* ps_3_0 */
20662 0x0200001f, 0x8001000a, 0x900f0001, /* dcl_color1 v1 */
20663 0x02000001, 0x800f0800, 0x90e40001, /* mov oC0, v1 */
20664 0x0000ffff
20666 static const DWORD ps3_texcoord_code[] =
20668 0xffff0300, /* ps_3_0 */
20669 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
20670 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
20671 0x0000ffff
20673 static const struct
20675 DWORD vs_version;
20676 const DWORD *vs;
20677 DWORD ps_version;
20678 const DWORD *ps;
20679 D3DCOLOR expected;
20680 BOOL allow_zero_alpha;
20681 BOOL partial;
20682 BOOL broken_warp;
20684 /* On AMD specular color is generally initialized to 0x00000000 and texcoords to 0xff000000
20685 * while on Nvidia it's the opposite. Just allow both.
20687 * Partially initialized varyings reliably handle the component that has been initialized.
20688 * The uninitialized components generally follow the rule above, with some exceptions on
20689 * radeon cards. r500 and r600 GPUs have been found to set uninitialized components to 0.0,
20690 * 0.5 and 1.0 without a sensible pattern. */
20691 tests[] =
20693 {D3DVS_VERSION(1, 1), vs1_code, 0, NULL, 0xffffffff},
20694 { 0, NULL, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff000000, TRUE},
20695 { 0, NULL, D3DPS_VERSION(2, 0), ps2_texcoord_code, 0xff000000, TRUE},
20696 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_diffuse_code, 0xffffffff},
20697 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_specular_code, 0xff000000, TRUE, FALSE, TRUE},
20698 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff000000, TRUE},
20699 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_diffuse_code, 0xffffffff},
20700 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_specular_code, 0xff000000, TRUE, FALSE, TRUE},
20701 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_texcoord_code, 0xff000000, TRUE},
20702 /* This test shows a lot of combinations of alpha and color that involve 1.0 and 0.0. Disable it.
20704 * AMD r500 sets alpha = 1.0, color = 0.0. Nvidia sets alpha = 1.0, color = 1.0. r600 Sets Alpha = 0.0,
20705 * color = 0.0. So far no combination with Alpha = 0.0, color = 1.0 has been found though.
20706 * {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_diffuse_code, 0xffffffff, FALSE, FALSE},
20708 * The same issues apply to the partially initialized COLOR0 varying, in addition to unreliable results
20709 * with partially initialized varyings in general.
20710 * {D3DVS_VERSION(3, 0), vs3_partial_code, D3DPS_VERSION(3, 0), ps3_diffuse_code, 0xff7fffff, TRUE, TRUE}, */
20711 {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_specular_code, 0xff000000, TRUE, FALSE, TRUE},
20712 {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_texcoord_code, 0xff000000, TRUE, FALSE, TRUE},
20713 {D3DVS_VERSION(1, 1), vs1_partial_code, 0, NULL, 0xff7fffff, FALSE, TRUE},
20714 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_diffuse_code, 0xff7fffff, FALSE, TRUE},
20715 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_specular_code, 0xff7f0000, TRUE, TRUE},
20716 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff7f0000, TRUE, TRUE},
20717 {D3DVS_VERSION(2, 0), vs2_partial_code, D3DPS_VERSION(2, 0), ps2_diffuse_code, 0xff7fffff, FALSE, TRUE},
20718 {D3DVS_VERSION(2, 0), vs2_partial_code, D3DPS_VERSION(2, 0), ps2_specular_code, 0xff7f0000, TRUE, TRUE},
20719 {D3DVS_VERSION(2, 0), vs2_partial_code, D3DPS_VERSION(2, 0), ps2_texcoord_code, 0xff7f0000, TRUE, TRUE},
20720 {D3DVS_VERSION(3, 0), vs3_partial_code, D3DPS_VERSION(3, 0), ps3_specular_code, 0x007f0000, FALSE, TRUE},
20721 {D3DVS_VERSION(3, 0), vs3_partial_code, D3DPS_VERSION(3, 0), ps3_texcoord_code, 0xff7f0000, TRUE, TRUE},
20723 IDirect3DDevice9 *device;
20724 IDirect3D9 *d3d;
20725 HWND window;
20726 HRESULT hr;
20727 D3DADAPTER_IDENTIFIER9 identifier;
20728 IDirect3DSurface9 *backbuffer;
20729 struct surface_readback rb;
20730 IDirect3DVertexShader9 *vs;
20731 IDirect3DPixelShader9 *ps;
20732 unsigned int i;
20733 ULONG refcount;
20734 D3DCAPS9 caps;
20735 D3DCOLOR color;
20736 BOOL warp;
20738 window = create_window();
20739 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20740 ok(!!d3d, "Failed to create a D3D object.\n");
20741 if (!(device = create_device(d3d, window, window, TRUE)))
20743 skip("Failed to create a D3D device, skipping tests.\n");
20744 IDirect3D9_Release(d3d);
20745 DestroyWindow(window);
20746 return;
20749 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
20750 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
20751 warp = adapter_is_warp(&identifier);
20753 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
20754 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
20756 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
20757 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
20759 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
20760 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
20761 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
20762 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
20763 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
20764 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
20765 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
20766 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
20767 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
20768 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
20769 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
20770 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
20771 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
20772 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#x.\n", hr);
20773 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
20774 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
20776 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
20777 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
20779 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
20781 if (caps.VertexShaderVersion < tests[i].vs_version
20782 || caps.PixelShaderVersion < tests[i].ps_version)
20784 skip("Vertex / pixel shader version not supported, skipping test %u.\n", i);
20785 continue;
20787 if (tests[i].vs)
20789 hr = IDirect3DDevice9_CreateVertexShader(device, tests[i].vs, &vs);
20790 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
20792 else
20794 vs = NULL;
20796 if (tests[i].ps)
20798 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].ps, &ps);
20799 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
20801 else
20803 ps = NULL;
20806 hr = IDirect3DDevice9_SetVertexShader(device, vs);
20807 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
20808 hr = IDirect3DDevice9_SetPixelShader(device, ps);
20809 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
20811 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
20812 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
20814 hr = IDirect3DDevice9_BeginScene(device);
20815 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
20817 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
20818 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20820 hr = IDirect3DDevice9_EndScene(device);
20821 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
20823 get_rt_readback(backbuffer, &rb);
20824 color = get_readback_color(&rb, 320, 240);
20825 ok(color_match(color, tests[i].expected, 1)
20826 || (tests[i].allow_zero_alpha && color_match(color, tests[i].expected & 0x00ffffff, 1))
20827 || (broken(warp && tests[i].broken_warp))
20828 || broken(tests[i].partial && color_match(color & 0x00ff0000, tests[i].expected & 0x00ff0000, 1)),
20829 "Got unexpected color 0x%08x, case %u.\n", color, i);
20830 release_surface_readback(&rb);
20832 if (vs)
20833 IDirect3DVertexShader9_Release(vs);
20834 if (ps)
20835 IDirect3DVertexShader9_Release(ps);
20838 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20839 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20841 IDirect3DSurface9_Release(backbuffer);
20842 refcount = IDirect3DDevice9_Release(device);
20843 ok(!refcount, "Device has %u references left.\n", refcount);
20844 IDirect3D9_Release(d3d);
20845 DestroyWindow(window);
20848 static void test_multisample_init(void)
20850 IDirect3DDevice9 *device;
20851 IDirect3D9 *d3d;
20852 IDirect3DSurface9 *back, *multi;
20853 ULONG refcount;
20854 HWND window;
20855 HRESULT hr;
20856 D3DCOLOR color;
20857 unsigned int x, y;
20858 struct surface_readback rb;
20859 BOOL all_zero = TRUE;
20861 window = create_window();
20862 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20863 ok(!!d3d, "Failed to create a D3D object.\n");
20865 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20866 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
20868 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample init test.\n");
20869 goto done;
20872 if (!(device = create_device(d3d, window, window, TRUE)))
20874 skip("Failed to create a D3D device, skipping tests.\n");
20875 goto done;
20878 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &back);
20879 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
20880 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
20881 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &multi, NULL);
20882 ok(SUCCEEDED(hr), "Failed to create multisampled render target, hr %#x.\n", hr);
20884 hr = IDirect3DDevice9_StretchRect(device, multi, NULL, back, NULL, D3DTEXF_POINT);
20885 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
20887 get_rt_readback(back, &rb);
20888 for (y = 0; y < 480; ++y)
20890 for (x = 0; x < 640; x++)
20892 color = get_readback_color(&rb, x, y);
20893 if (!color_match(color, 0x00000000, 0))
20895 all_zero = FALSE;
20896 break;
20899 if (!all_zero)
20900 break;
20902 release_surface_readback(&rb);
20903 ok(all_zero, "Got unexpected color 0x%08x, position %ux%u.\n", color, x, y);
20905 IDirect3DSurface9_Release(multi);
20906 IDirect3DSurface9_Release(back);
20908 refcount = IDirect3DDevice9_Release(device);
20909 ok(!refcount, "Device has %u references left.\n", refcount);
20911 done:
20912 IDirect3D9_Release(d3d);
20913 DestroyWindow(window);
20916 static void test_texture_blending(void)
20918 #define STATE_END() {0xffffffff, 0xffffffff}
20919 #define IS_STATE_END(s) (s.name == 0xffffffff && s.value == 0xffffffff)
20921 IDirect3DTexture9 *texture_bumpmap, *texture_red;
20922 IDirect3DSurface9 *backbuffer;
20923 struct surface_readback rb;
20924 D3DLOCKED_RECT locked_rect;
20925 IDirect3DDevice9 *device;
20926 unsigned int i, j, k;
20927 IDirect3D9 *d3d;
20928 D3DCOLOR color;
20929 ULONG refcount;
20930 D3DCAPS9 caps;
20931 HWND window;
20932 HRESULT hr;
20934 static const struct
20936 struct vec3 position;
20937 DWORD diffuse;
20939 quad[] =
20941 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
20942 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
20943 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
20944 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
20947 static const float bumpenvmat[4] = {1.0f, 1.0f, 0.0f, 0.0f};
20949 struct texture_stage_state
20951 D3DTEXTURESTAGESTATETYPE name;
20952 DWORD value;
20955 struct texture_stage
20957 enum
20959 TEXTURE_INVALID,
20960 TEXTURE_NONE,
20961 TEXTURE_BUMPMAP,
20962 TEXTURE_RED,
20964 texture;
20965 struct texture_stage_state state[20];
20968 static const struct texture_stage default_stage_state =
20970 TEXTURE_NONE,
20972 {D3DTSS_COLOROP, D3DTOP_DISABLE},
20973 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
20974 {D3DTSS_COLORARG2, D3DTA_CURRENT},
20975 {D3DTSS_ALPHAOP, D3DTOP_DISABLE},
20976 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
20977 {D3DTSS_ALPHAARG2, D3DTA_CURRENT},
20978 {D3DTSS_BUMPENVMAT00, 0},
20979 {D3DTSS_BUMPENVMAT01, 0},
20980 {D3DTSS_BUMPENVMAT10, 0},
20981 {D3DTSS_BUMPENVMAT11, 0},
20982 {D3DTSS_BUMPENVLSCALE, 0},
20983 {D3DTSS_BUMPENVLOFFSET, 0},
20984 {D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE},
20985 {D3DTSS_COLORARG0, D3DTA_CURRENT},
20986 {D3DTSS_ALPHAARG0, D3DTA_CURRENT},
20987 {D3DTSS_RESULTARG, D3DTA_CURRENT},
20988 {D3DTSS_CONSTANT, 0},
20989 STATE_END(),
20993 const struct test
20995 DWORD tex_op_caps;
20996 D3DCOLOR expected_color;
20997 struct texture_stage stage[8];
20999 tests[] =
21002 D3DTEXOPCAPS_DISABLE,
21003 0x80ffff02,
21006 TEXTURE_NONE,
21008 STATE_END(),
21014 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
21015 0x80ffff02,
21018 TEXTURE_NONE,
21020 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21021 {D3DTSS_COLORARG1, D3DTA_CURRENT},
21022 STATE_END(),
21025 {TEXTURE_INVALID}
21029 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
21030 0x80ffff02,
21033 TEXTURE_NONE,
21035 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21036 {D3DTSS_COLORARG1, D3DTA_CURRENT},
21037 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21038 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21039 STATE_END(),
21045 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
21046 0x80ffff02,
21049 TEXTURE_NONE,
21051 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21052 {D3DTSS_COLORARG1, D3DTA_DIFFUSE},
21053 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21054 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
21055 STATE_END(),
21061 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
21062 0x00000000,
21065 TEXTURE_NONE,
21067 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21068 {D3DTSS_COLORARG1, D3DTA_TEMP},
21069 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21070 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21071 STATE_END(),
21077 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_SUBTRACT,
21078 0x80f0f000,
21081 TEXTURE_NONE,
21083 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21084 {D3DTSS_COLORARG1, D3DTA_CURRENT},
21085 STATE_END(),
21089 TEXTURE_NONE,
21091 {D3DTSS_COLOROP, D3DTOP_SUBTRACT},
21092 {D3DTSS_COLORARG1, D3DTA_CURRENT},
21093 {D3DTSS_COLORARG2, D3DTA_CONSTANT},
21094 {D3DTSS_CONSTANT, 0x0f0f0f0f},
21095 STATE_END(),
21098 {TEXTURE_INVALID}
21102 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_SUBTRACT,
21103 0x71f0f000,
21106 TEXTURE_NONE,
21108 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21109 {D3DTSS_COLORARG1, D3DTA_CURRENT},
21110 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21111 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21112 STATE_END(),
21116 TEXTURE_NONE,
21118 {D3DTSS_COLOROP, D3DTOP_SUBTRACT},
21119 {D3DTSS_COLORARG1, D3DTA_CURRENT},
21120 {D3DTSS_COLORARG2, D3DTA_CONSTANT},
21121 {D3DTSS_ALPHAOP, D3DTOP_SUBTRACT},
21122 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21123 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
21124 {D3DTSS_CONSTANT, 0x0f0f0f0f},
21125 STATE_END(),
21128 {TEXTURE_INVALID}
21133 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
21134 0x80ff0000,
21137 TEXTURE_BUMPMAP,
21139 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21140 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21141 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21142 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21143 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21144 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21145 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
21146 STATE_END(),
21151 TEXTURE_RED,
21153 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21154 STATE_END(),
21157 {TEXTURE_INVALID}
21161 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
21162 0x80ff0000,
21165 TEXTURE_BUMPMAP,
21167 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21168 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21169 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21170 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21171 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21172 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21173 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
21174 STATE_END(),
21178 TEXTURE_RED,
21180 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21181 STATE_END(),
21184 {TEXTURE_INVALID}
21188 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
21189 0x80ff0000,
21192 TEXTURE_BUMPMAP,
21194 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21195 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21196 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21197 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21198 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21199 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21200 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21201 STATE_END(),
21205 TEXTURE_RED,
21207 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21208 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21209 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21210 STATE_END(),
21213 {TEXTURE_INVALID}
21217 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
21218 0x00ff0000,
21221 TEXTURE_BUMPMAP,
21223 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21224 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21225 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21226 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21227 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21228 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21229 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21230 STATE_END(),
21234 TEXTURE_RED,
21236 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21237 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21238 {D3DTSS_COLORARG2, D3DTA_CURRENT},
21239 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21240 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21241 STATE_END(),
21244 {TEXTURE_INVALID}
21248 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
21249 0x80ff0000,
21252 TEXTURE_BUMPMAP,
21254 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21255 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21256 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21257 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21258 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21259 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21260 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21261 STATE_END(),
21265 TEXTURE_RED,
21267 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21268 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21269 {D3DTSS_COLORARG2, D3DTA_CURRENT},
21270 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21271 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21272 STATE_END(),
21275 {TEXTURE_INVALID}
21280 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
21281 | D3DTEXOPCAPS_ADD,
21282 0x80ff0000,
21285 TEXTURE_BUMPMAP,
21287 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21288 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21289 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21290 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21291 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21292 {D3DTSS_ALPHAOP, D3DTOP_ADD},
21293 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
21294 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
21295 {D3DTSS_CONSTANT, 0x0fffffff},
21296 STATE_END(),
21300 TEXTURE_RED,
21302 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21303 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21304 {D3DTSS_COLORARG2, D3DTA_CURRENT},
21305 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21306 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21307 STATE_END(),
21310 {TEXTURE_INVALID}
21314 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
21315 | D3DTEXOPCAPS_MODULATE2X,
21316 0x80ff0000,
21319 TEXTURE_BUMPMAP,
21321 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21322 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21323 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21324 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21325 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21326 {D3DTSS_ALPHAOP, D3DTOP_MODULATE2X},
21327 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
21328 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
21329 {D3DTSS_CONSTANT, 0x01ffffff},
21330 STATE_END(),
21334 TEXTURE_RED,
21336 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21337 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21338 {D3DTSS_COLORARG2, D3DTA_CURRENT},
21339 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21340 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21341 STATE_END(),
21344 {TEXTURE_INVALID}
21348 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
21349 | D3DTEXOPCAPS_MODULATE2X,
21350 0x80ffff00,
21353 TEXTURE_BUMPMAP,
21355 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21356 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21357 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21358 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21359 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21360 {D3DTSS_ALPHAOP, D3DTOP_MODULATE2X},
21361 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21362 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
21363 {D3DTSS_CONSTANT, 0x01ffffff},
21364 STATE_END(),
21368 TEXTURE_RED,
21370 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21371 {D3DTSS_COLORARG1, D3DTA_CURRENT},
21372 {D3DTSS_COLORARG2, D3DTA_CURRENT},
21373 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21374 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21375 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
21376 {D3DTSS_ALPHAARG0, D3DTA_CONSTANT},
21377 STATE_END(),
21380 {TEXTURE_INVALID}
21384 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
21385 0x01234567,
21388 TEXTURE_NONE,
21390 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21391 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
21392 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21393 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
21394 {D3DTSS_RESULTARG, D3DTA_TEMP},
21395 {D3DTSS_CONSTANT, 0x01234567},
21396 STATE_END(),
21400 TEXTURE_BUMPMAP,
21402 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21403 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21404 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21405 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21406 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21407 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21408 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21409 {D3DTSS_RESULTARG, D3DTA_TEMP},
21410 STATE_END(),
21414 TEXTURE_RED,
21416 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21417 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21418 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21419 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
21420 STATE_END(),
21424 TEXTURE_NONE,
21426 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21427 {D3DTSS_COLORARG1, D3DTA_TEMP},
21428 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21429 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21430 STATE_END(),
21433 {TEXTURE_INVALID}
21437 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
21438 0x00234567,
21441 TEXTURE_NONE,
21443 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21444 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
21445 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21446 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
21447 {D3DTSS_RESULTARG, D3DTA_TEMP},
21448 {D3DTSS_CONSTANT, 0x01234567},
21449 STATE_END(),
21453 TEXTURE_BUMPMAP,
21455 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21456 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21457 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21458 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21459 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21460 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21461 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21462 STATE_END(),
21466 TEXTURE_RED,
21468 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21469 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21470 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21471 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
21472 STATE_END(),
21476 TEXTURE_NONE,
21478 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21479 {D3DTSS_COLORARG1, D3DTA_TEMP},
21480 STATE_END(),
21483 {TEXTURE_INVALID}
21487 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
21488 0x01234567,
21491 TEXTURE_NONE,
21493 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21494 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
21495 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21496 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
21497 {D3DTSS_RESULTARG, D3DTA_TEMP},
21498 {D3DTSS_CONSTANT, 0x01234567},
21499 STATE_END(),
21503 TEXTURE_BUMPMAP,
21505 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21506 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21507 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21508 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21509 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21510 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21511 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21512 {D3DTSS_RESULTARG, D3DTA_TEMP},
21513 STATE_END(),
21517 TEXTURE_RED,
21519 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21520 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21521 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21522 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
21523 STATE_END(),
21527 TEXTURE_NONE,
21529 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21530 {D3DTSS_COLORARG1, D3DTA_TEMP},
21531 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21532 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21533 STATE_END(),
21536 {TEXTURE_INVALID}
21540 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
21541 0x01234567,
21544 TEXTURE_NONE,
21546 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21547 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
21548 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21549 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
21550 {D3DTSS_RESULTARG, D3DTA_CURRENT},
21551 {D3DTSS_CONSTANT, 0x01234567},
21552 STATE_END(),
21556 TEXTURE_BUMPMAP,
21558 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21559 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21560 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21561 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21562 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21563 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21564 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21565 {D3DTSS_RESULTARG, D3DTA_TEMP},
21566 STATE_END(),
21570 TEXTURE_RED,
21572 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21573 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21574 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21575 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
21576 {D3DTSS_RESULTARG, D3DTA_TEMP},
21577 STATE_END(),
21581 TEXTURE_NONE,
21583 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21584 {D3DTSS_COLORARG1, D3DTA_CURRENT},
21585 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21586 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21587 {D3DTSS_RESULTARG, D3DTA_CURRENT},
21588 STATE_END(),
21591 {TEXTURE_INVALID}
21596 window = create_window();
21597 d3d = Direct3DCreate9(D3D_SDK_VERSION);
21598 ok(!!d3d, "Failed to create a D3D object.\n");
21599 if (!(device = create_device(d3d, window, window, TRUE)))
21601 skip("Failed to create a D3D device.\n");
21602 goto done;
21605 memset(&caps, 0, sizeof(caps));
21606 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
21607 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr %#x.\n", hr);
21609 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
21611 skip("D3DPMISCCAPS_TSSARGTEMP not supported.\n");
21612 IDirect3DDevice9_Release(device);
21613 goto done;
21616 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_PERSTAGECONSTANT))
21618 skip("D3DPMISCCAPS_PERSTAGECONSTANT not supported.\n");
21619 IDirect3DDevice9_Release(device);
21620 goto done;
21623 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
21624 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_V8U8)))
21626 skip("D3DFMT_V8U8 not supported for legacy bump mapping.\n");
21627 IDirect3DDevice9_Release(device);
21628 goto done;
21631 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
21632 ok(hr == D3D_OK, "Can't get back buffer, hr %#x.\n", hr);
21634 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture_bumpmap, NULL);
21635 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr %#x.\n", hr);
21636 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture_red, NULL);
21637 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr %#x.\n", hr);
21639 memset(&locked_rect, 0, sizeof(locked_rect));
21640 hr = IDirect3DTexture9_LockRect(texture_bumpmap, 0, &locked_rect, NULL, 0);
21641 ok(SUCCEEDED(hr), "LockRect failed, hr %#x.\n", hr);
21642 *((WORD *)locked_rect.pBits) = 0xff00;
21643 hr = IDirect3DTexture9_UnlockRect(texture_bumpmap, 0);
21644 ok(SUCCEEDED(hr), "UnlockRect failed, hr %#x.\n", hr);
21646 memset(&locked_rect, 0, sizeof(locked_rect));
21647 hr = IDirect3DTexture9_LockRect(texture_red, 0, &locked_rect, NULL, 0);
21648 ok(SUCCEEDED(hr), "LockRect failed, hr %#x.\n", hr);
21649 *((DWORD *)locked_rect.pBits) = 0x00ff0000;
21650 hr = IDirect3DTexture9_UnlockRect(texture_red, 0);
21651 ok(SUCCEEDED(hr), "UnlockRect failed, hr %#x.\n", hr);
21653 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
21654 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
21655 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
21656 ok(hr == D3D_OK, "Failed to disable lighting, hr %#x.\n", hr);
21658 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
21660 const struct test *current_test = &tests[i];
21662 if ((caps.TextureOpCaps & current_test->tex_op_caps) != current_test->tex_op_caps)
21664 skip("Texture operations %#x not supported.\n", current_test->tex_op_caps);
21665 continue;
21668 for (j = 0; j < caps.MaxTextureBlendStages; ++j)
21670 IDirect3DTexture9 *current_texture = NULL;
21672 for (k = 0; !IS_STATE_END(default_stage_state.state[k]); ++k)
21674 hr = IDirect3DDevice9_SetTextureStageState(device, j,
21675 default_stage_state.state[k].name, default_stage_state.state[k].value);
21676 ok(SUCCEEDED(hr), "Test %u: SetTextureStageState failed, hr %#x.\n", i, hr);
21679 if (current_test->stage[j].texture != TEXTURE_INVALID)
21681 const struct texture_stage_state *current_state = current_test->stage[j].state;
21683 switch (current_test->stage[j].texture)
21685 case TEXTURE_RED:
21686 current_texture = texture_red;
21687 break;
21688 case TEXTURE_BUMPMAP:
21689 current_texture = texture_bumpmap;
21690 break;
21691 default:
21692 current_texture = NULL;
21693 break;
21696 for (k = 0; !IS_STATE_END(current_state[k]); ++k)
21698 hr = IDirect3DDevice9_SetTextureStageState(device, j,
21699 current_state[k].name, current_state[k].value);
21700 ok(SUCCEEDED(hr), "Test %u: SetTextureStageState failed, hr %#x.\n", i, hr);
21704 hr = IDirect3DDevice9_SetTexture(device, j, (IDirect3DBaseTexture9 *)current_texture);
21705 ok(SUCCEEDED(hr), "Test %u: SetTexture failed, hr %#x.\n", i, hr);
21708 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
21709 ok(hr == D3D_OK, "Test %u: IDirect3DDevice9_Clear failed, hr %#x.\n", i, hr);
21711 hr = IDirect3DDevice9_BeginScene(device);
21712 ok(SUCCEEDED(hr), "Test %u: BeginScene failed, hr %#x.\n", i, hr);
21713 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
21714 ok(SUCCEEDED(hr), "Test %u: DrawPrimitiveUP failed, hr %#x.\n", i, hr);
21715 hr = IDirect3DDevice9_EndScene(device);
21716 ok(SUCCEEDED(hr), "Test %u: EndScene failed, hr %#x.\n", i, hr);
21718 get_rt_readback(backbuffer, &rb);
21719 color = get_readback_color(&rb, 320, 240);
21720 ok(color_match(color, current_test->expected_color, 1),
21721 "Test %u: Got color 0x%08x, expected 0x%08x.\n", i, color, current_test->expected_color);
21722 release_surface_readback(&rb);
21723 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21724 ok(SUCCEEDED(hr), "Test %u: Present failed, hr %#x.\n", i, hr);
21727 IDirect3DTexture9_Release(texture_bumpmap);
21728 IDirect3DTexture9_Release(texture_red);
21729 IDirect3DSurface9_Release(backbuffer);
21730 refcount = IDirect3DDevice9_Release(device);
21731 ok(!refcount, "Device has %u references left.\n", refcount);
21732 done:
21733 IDirect3D9_Release(d3d);
21734 DestroyWindow(window);
21737 static void test_color_clamping(void)
21739 static const D3DMATRIX mat =
21741 1.0f, 0.0f, 0.0f, 0.0f,
21742 0.0f, 1.0f, 0.0f, 0.0f,
21743 0.0f, 0.0f, 1.0f, 0.0f,
21744 0.0f, 0.0f, 0.0f, 1.0f,
21745 }}};
21746 static const struct vec3 quad[] =
21748 {-1.0f, -1.0f, 0.1f},
21749 {-1.0f, 1.0f, 0.1f},
21750 { 1.0f, -1.0f, 0.1f},
21751 { 1.0f, 1.0f, 0.1f},
21753 static const DWORD vs1_code[] =
21755 0xfffe0101, /* vs_1_1 */
21756 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
21757 0x00000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
21758 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
21759 0x00000002, 0xd00f0000, 0xa0e40000, 0xa0e40000, /* add oD0, c0, c0 */
21760 0x00000002, 0xd00f0001, 0xa0e40000, 0xa0e40000, /* add oD1, c0, c0 */
21761 0x0000ffff
21763 static const DWORD vs2_code[] =
21765 0xfffe0200, /* vs_2_0 */
21766 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
21767 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
21768 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
21769 0x03000002, 0xd00f0000, 0xa0e40000, 0xa0e40000, /* add oD0, c0, c0 */
21770 0x03000002, 0xd00f0001, 0xa0e40000, 0xa0e40000, /* add oD1, c0, c0 */
21771 0x0000ffff
21773 static const DWORD vs3_code[] =
21775 0xfffe0300, /* vs_3_0 */
21776 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
21777 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
21778 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
21779 0x0200001f, 0x8001000a, 0xe00f0002, /* dcl_color1 o2 */
21780 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
21781 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
21782 0x03000002, 0xe00f0001, 0xa0e40000, 0xa0e40000, /* add o1, c0, c0 */
21783 0x03000002, 0xe00f0002, 0xa0e40000, 0xa0e40000, /* add o2, c0, c0 */
21784 0x0000ffff
21786 static const DWORD ps1_code[] =
21788 0xffff0101, /* ps_1_1 */
21789 0x00000051, 0xa00f0000, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000, /* def c0, 0.25, 0.25, 0.25, 0.25 */
21790 0x00000002, 0x800f0000, 0x90e40000, 0x90e40001, /* add r0, v0, v1 */
21791 0x00000005, 0x800f0000, 0x80e40000, 0xa0e40000, /* mul r0, r0, c0 */
21792 0x0000ffff
21794 static const DWORD ps2_code[] =
21796 0xffff0200, /* ps_2_0 */
21797 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
21798 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
21799 0x05000051, 0xa00f0000, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000, /* def c0, 0.25, 0.25, 0.25, 0.25 */
21800 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
21801 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
21802 0x03000005, 0x800f0000, 0x80e40000, 0xa0e40000, /* mul r0, r0, c0 */
21803 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
21804 0x0000ffff
21806 static const DWORD ps3_code[] =
21808 0xffff0300, /* ps_3_0 */
21809 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
21810 0x0200001f, 0x8001000a, 0x900f0001, /* dcl_color1 v1 */
21811 0x05000051, 0xa00f0000, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000, /* def c0, 0.25, 0.25, 0.25, 0.25 */
21812 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
21813 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
21814 0x03000005, 0x800f0800, 0x80e40000, 0xa0e40000, /* mul oC0, r0, c0 */
21815 0x0000ffff
21817 static const struct
21819 DWORD vs_version;
21820 const DWORD *vs;
21821 DWORD ps_version;
21822 const DWORD *ps;
21823 D3DCOLOR expected, broken;
21825 tests[] =
21827 {0, NULL, 0, NULL, 0x00404040},
21828 {0, NULL, D3DPS_VERSION(1, 1), ps1_code, 0x00404040, 0x00808080},
21829 {D3DVS_VERSION(1, 1), vs1_code, 0, NULL, 0x00404040},
21830 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_code, 0x007f7f7f},
21831 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_code, 0x007f7f7f},
21832 {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_code, 0x00ffffff},
21834 IDirect3DVertexShader9 *vs;
21835 IDirect3DPixelShader9 *ps;
21836 IDirect3DDevice9 *device;
21837 IDirect3D9 *d3d9;
21838 unsigned int i;
21839 ULONG refcount;
21840 D3DCOLOR color;
21841 D3DCAPS9 caps;
21842 HWND window;
21843 HRESULT hr;
21845 window = create_window();
21846 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
21847 ok(!!d3d9, "Failed to create a D3D object.\n");
21848 if (!(device = create_device(d3d9, window, window, TRUE)))
21850 skip("Failed to create a D3D device, skipping tests.\n");
21851 IDirect3D9_Release(d3d9);
21852 DestroyWindow(window);
21853 return;
21856 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
21857 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
21859 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
21860 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
21861 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
21862 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
21863 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
21864 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
21865 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
21866 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
21867 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
21868 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
21869 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
21870 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
21871 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
21872 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#x.\n", hr);
21873 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
21874 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
21875 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
21876 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
21878 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xff404040);
21879 ok(SUCCEEDED(hr), "Failed to set texture factor, hr %#x.\n", hr);
21880 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
21881 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
21882 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
21883 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
21884 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_SPECULAR);
21885 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
21886 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_MODULATE);
21887 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
21888 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
21889 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
21890 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
21891 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
21893 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
21894 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
21896 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
21898 if (caps.VertexShaderVersion < tests[i].vs_version
21899 || caps.PixelShaderVersion < tests[i].ps_version)
21901 skip("Vertex / pixel shader version not supported, skipping test %u.\n", i);
21902 continue;
21904 if (tests[i].vs)
21906 hr = IDirect3DDevice9_CreateVertexShader(device, tests[i].vs, &vs);
21907 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
21909 else
21911 vs = NULL;
21913 if (tests[i].ps)
21915 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].ps, &ps);
21916 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
21918 else
21920 ps = NULL;
21923 hr = IDirect3DDevice9_SetVertexShader(device, vs);
21924 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
21925 hr = IDirect3DDevice9_SetPixelShader(device, ps);
21926 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
21928 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
21929 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21931 hr = IDirect3DDevice9_BeginScene(device);
21932 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21934 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
21935 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
21937 hr = IDirect3DDevice9_EndScene(device);
21938 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
21940 color = getPixelColor(device, 320, 240);
21941 ok(color_match(color, tests[i].expected, 1) || broken(color_match(color, tests[i].broken, 1)),
21942 "Got unexpected color 0x%08x, case %u.\n", color, i);
21944 if (vs)
21945 IDirect3DVertexShader9_Release(vs);
21946 if (ps)
21947 IDirect3DVertexShader9_Release(ps);
21950 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21951 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
21953 refcount = IDirect3DDevice9_Release(device);
21954 ok(!refcount, "Device has %u references left.\n", refcount);
21955 IDirect3D9_Release(d3d9);
21956 DestroyWindow(window);
21959 static void test_line_antialiasing_blending(void)
21961 IDirect3DDevice9 *device;
21962 IDirect3D9 *d3d9;
21963 ULONG refcount;
21964 D3DCOLOR color;
21965 D3DCAPS9 caps;
21966 HWND window;
21967 HRESULT hr;
21969 static const struct
21971 struct vec3 position;
21972 DWORD diffuse;
21974 green_quad[] =
21976 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
21977 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
21978 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
21979 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
21981 static const struct
21983 struct vec3 position;
21984 DWORD diffuse;
21986 red_quad[] =
21988 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
21989 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
21990 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
21991 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
21994 window = create_window();
21995 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
21996 ok(!!d3d9, "Failed to create a D3D object.\n");
21997 if (!(device = create_device(d3d9, window, window, TRUE)))
21999 skip("Failed to create a D3D device.\n");
22000 IDirect3D9_Release(d3d9);
22001 DestroyWindow(window);
22002 return;
22005 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
22006 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
22007 trace("Line antialiasing support: %#x.\n", caps.LineCaps & D3DLINECAPS_ANTIALIAS);
22009 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
22010 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
22011 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
22012 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
22013 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
22014 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
22016 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
22017 ok(SUCCEEDED(hr), "Failed to enable blending, hr %#x.\n", hr);
22018 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_BLENDOP, D3DBLENDOP_ADD);
22019 ok(SUCCEEDED(hr), "Failed to set blend op, hr %#x.\n", hr);
22020 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
22021 ok(SUCCEEDED(hr), "Failed to set src blend, hr %#x.\n", hr);
22022 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_DESTALPHA);
22023 ok(SUCCEEDED(hr), "Failed to set dest blend, hr %#x.\n", hr);
22025 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
22026 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
22027 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
22028 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
22029 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
22030 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#x.\n", hr);
22031 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
22032 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#x.\n", hr);
22034 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
22035 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
22037 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
22038 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22039 hr = IDirect3DDevice9_BeginScene(device);
22040 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22041 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
22042 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22043 hr = IDirect3DDevice9_EndScene(device);
22044 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22045 color = getPixelColor(device, 320, 240);
22046 ok(color_match(color, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color);
22048 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
22049 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22050 hr = IDirect3DDevice9_BeginScene(device);
22051 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22052 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
22053 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22054 hr = IDirect3DDevice9_EndScene(device);
22055 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22056 color = getPixelColor(device, 320, 240);
22057 ok(color_match(color, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color);
22059 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
22060 ok(SUCCEEDED(hr), "Failed to disable blending, hr %#x.\n", hr);
22062 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
22063 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22064 hr = IDirect3DDevice9_BeginScene(device);
22065 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22066 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
22067 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22068 hr = IDirect3DDevice9_EndScene(device);
22069 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22070 color = getPixelColor(device, 320, 240);
22071 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
22073 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
22074 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22075 hr = IDirect3DDevice9_BeginScene(device);
22076 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22077 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
22078 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22079 hr = IDirect3DDevice9_EndScene(device);
22080 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22081 color = getPixelColor(device, 320, 240);
22082 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
22084 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ANTIALIASEDLINEENABLE, TRUE);
22085 ok(SUCCEEDED(hr), "Failed to enable line antialiasing, hr %#x.\n", hr);
22087 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
22088 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22089 hr = IDirect3DDevice9_BeginScene(device);
22090 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22091 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
22092 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22093 hr = IDirect3DDevice9_EndScene(device);
22094 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22095 color = getPixelColor(device, 320, 240);
22096 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
22098 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
22099 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22100 hr = IDirect3DDevice9_BeginScene(device);
22101 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22102 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
22103 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22104 hr = IDirect3DDevice9_EndScene(device);
22105 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22106 color = getPixelColor(device, 320, 240);
22107 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
22109 refcount = IDirect3DDevice9_Release(device);
22110 ok(!refcount, "Device has %u references left.\n", refcount);
22111 IDirect3D9_Release(d3d9);
22112 DestroyWindow(window);
22115 static void test_dsy(void)
22117 static const DWORD vs_code[] =
22119 0xfffe0300, /* vs_3_0 */
22120 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
22121 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
22122 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
22123 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
22124 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
22125 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
22126 0x0000ffff
22128 static const DWORD ps_code[] =
22130 0xffff0300, /* ps_3_0 */
22131 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
22132 0x05000051, 0xa00f0000, 0x43700000, 0x3f000000, 0x00000000, 0x00000000, /* def c0, 240.0, 0.5, 0.0, 0.0 */
22133 0x0200005c, 0x800f0000, 0x90e40000, /* dsy r0, v0 */
22134 0x03000005, 0x800f0000, 0x80e40000, 0xa0000000, /* mul r0, r0, c0.x */
22135 0x03000002, 0x800f0800, 0x80e40000, 0xa0550000, /* add oC0, r0, c0.y */
22136 0x0000ffff
22138 static const struct
22140 struct vec3 pos;
22141 D3DCOLOR color;
22143 quad[] =
22145 {{-1.0f, -1.0f, 0.1f}, 0x00ff0000},
22146 {{-1.0f, 1.0f, 0.1f}, 0x0000ff00},
22147 {{ 1.0f, -1.0f, 0.1f}, 0x00ff0000},
22148 {{ 1.0f, 1.0f, 0.1f}, 0x0000ff00},
22150 IDirect3DSurface9 *backbuffer, *rt;
22151 IDirect3DVertexShader9 *vs;
22152 IDirect3DPixelShader9 *ps;
22153 IDirect3DDevice9 *device;
22154 IDirect3D9 *d3d;
22155 ULONG refcount;
22156 D3DCAPS9 caps;
22157 DWORD color;
22158 HWND window;
22159 HRESULT hr;
22161 window = create_window();
22162 d3d = Direct3DCreate9(D3D_SDK_VERSION);
22163 ok(!!d3d, "Failed to create a D3D object.\n");
22164 if (!(device = create_device(d3d, window, window, TRUE)))
22166 skip("Failed to create a D3D device, skipping tests.\n");
22167 goto done;
22170 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
22171 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
22172 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
22174 skip("No ps_3_0 support, skipping dsy tests.\n");
22175 IDirect3DDevice9_Release(device);
22176 goto done;
22179 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
22180 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
22182 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
22183 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
22184 ok(SUCCEEDED(hr), "Failed to create offscreen render target, hr %#x.\n", hr);
22185 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
22186 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
22188 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
22189 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
22190 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
22191 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
22193 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
22194 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
22195 hr = IDirect3DDevice9_SetVertexShader(device, vs);
22196 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
22197 hr = IDirect3DDevice9_SetPixelShader(device, ps);
22198 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
22200 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
22201 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22202 hr = IDirect3DDevice9_BeginScene(device);
22203 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22204 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
22205 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
22206 hr = IDirect3DDevice9_EndScene(device);
22207 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22209 color = getPixelColor(device, 360, 240);
22210 ok(color_match(color, 0x00ff007f, 1), "Got unexpected color 0x%08x.\n", color);
22212 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
22213 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
22215 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
22216 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22217 hr = IDirect3DDevice9_BeginScene(device);
22218 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22219 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
22220 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
22221 hr = IDirect3DDevice9_EndScene(device);
22222 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22224 color = getPixelColor(device, 360, 240);
22225 ok(color_match(color, 0x00ff007f, 1), "Got unexpected color 0x%08x.\n", color);
22227 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
22228 ok(SUCCEEDED(hr), "Failed to present frame, hr %#x.\n", hr);
22230 IDirect3DSurface9_Release(rt);
22231 IDirect3DSurface9_Release(backbuffer);
22232 IDirect3DVertexShader9_Release(vs);
22233 IDirect3DPixelShader9_Release(ps);
22235 refcount = IDirect3DDevice9_Release(device);
22236 ok(!refcount, "Device has %u references left.\n", refcount);
22237 done:
22238 IDirect3D9_Release(d3d);
22239 DestroyWindow(window);
22242 static void test_evict_bound_resources(void)
22244 IDirect3DVertexBuffer9 *vb;
22245 IDirect3DIndexBuffer9 *ib;
22246 IDirect3DDevice9 *device;
22247 IDirect3D9 *d3d9;
22248 ULONG refcount;
22249 D3DCOLOR color;
22250 HWND window;
22251 void *data;
22252 HRESULT hr;
22254 static const struct
22256 struct vec3 position;
22257 DWORD diffuse;
22259 green_quad[] =
22261 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
22262 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
22263 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
22264 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
22266 static const unsigned short indices[] = {0, 1, 2, 3, 2, 1};
22268 window = create_window();
22269 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
22270 ok(!!d3d9, "Failed to create a D3D object.\n");
22272 if (!(device = create_device(d3d9, window, window, TRUE)))
22274 skip("Failed to create a D3D device.\n");
22275 IDirect3D9_Release(d3d9);
22276 DestroyWindow(window);
22277 return;
22280 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0,
22281 D3DFMT_INDEX16, D3DPOOL_MANAGED, &ib, NULL);
22282 ok(SUCCEEDED(hr), "Failed to create index buffer, hr %#x.\n", hr);
22284 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(green_quad), 0,
22285 D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &vb, NULL);
22286 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
22288 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
22289 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
22290 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
22291 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
22292 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
22293 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
22295 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
22296 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
22298 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(green_quad), &data, 0);
22299 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#x.\n", hr);
22300 memcpy(data, green_quad, sizeof(green_quad));
22301 hr = IDirect3DVertexBuffer9_Unlock(vb);
22302 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#x.\n", hr);
22304 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), &data, 0);
22305 ok(hr == D3D_OK, "Failed to lock index buffer, hr %#x.\n", hr);
22306 memcpy(data, indices, sizeof(indices));
22307 hr = IDirect3DIndexBuffer9_Unlock(ib);
22308 ok(hr == D3D_OK, "Failed to unlock index buffer, hr %#x.\n", hr);
22310 hr = IDirect3DDevice9_SetIndices(device, ib);
22311 ok(hr == D3D_OK, "Failed to set index buffer, hr %#x.\n", hr);
22312 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(*green_quad));
22313 ok(hr == D3D_OK, "Failed to set stream source, hr %#x.\n", hr);
22315 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
22316 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22317 hr = IDirect3DDevice9_BeginScene(device);
22318 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22319 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
22320 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22321 hr = IDirect3DDevice9_EndScene(device);
22322 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22323 color = getPixelColor(device, 320, 240);
22324 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
22326 hr = IDirect3DDevice9_EvictManagedResources(device);
22327 ok(hr == D3D_OK, "Failed to evict managed resources, hr %#x.\n", hr);
22329 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
22330 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22331 hr = IDirect3DDevice9_BeginScene(device);
22332 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22333 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
22334 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22335 hr = IDirect3DDevice9_EndScene(device);
22336 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22337 color = getPixelColor(device, 320, 240);
22338 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
22340 IDirect3DIndexBuffer9_Release(ib);
22341 IDirect3DVertexBuffer9_Release(vb);
22342 refcount = IDirect3DDevice9_Release(device);
22343 ok(!refcount, "Device has %u references left.\n", refcount);
22344 IDirect3D9_Release(d3d9);
22345 DestroyWindow(window);
22348 /* This test shows that 0xffff is valid index in D3D9. */
22349 static void test_max_index16(void)
22351 static const struct vertex
22353 struct vec3 position;
22354 DWORD diffuse;
22356 green_quad[] =
22358 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22359 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22360 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22361 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22363 static const unsigned short indices[] = {0, 1, 2, 0xffff};
22364 static const unsigned int vertex_count = 0xffff + 1;
22366 D3DADAPTER_IDENTIFIER9 identifier;
22367 IDirect3DVertexBuffer9 *vb;
22368 IDirect3DIndexBuffer9 *ib;
22369 IDirect3DDevice9 *device;
22370 struct vertex *vb_data;
22371 IDirect3D9 *d3d9;
22372 ULONG refcount;
22373 D3DCOLOR color;
22374 D3DCAPS9 caps;
22375 HWND window;
22376 void *data;
22377 HRESULT hr;
22378 BOOL warp;
22380 window = create_window();
22381 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
22382 ok(!!d3d9, "Failed to create a D3D object.\n");
22384 hr = IDirect3D9_GetAdapterIdentifier(d3d9, D3DADAPTER_DEFAULT, 0, &identifier);
22385 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
22386 warp = adapter_is_warp(&identifier);
22388 if (!(device = create_device(d3d9, window, window, TRUE)))
22390 skip("Failed to create a D3D device.\n");
22391 IDirect3D9_Release(d3d9);
22392 DestroyWindow(window);
22393 return;
22396 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
22397 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
22398 if (caps.MaxVertexIndex < 0xffff)
22400 skip("Max vertex index is lower than 0xffff (%#x).\n", caps.MaxVertexIndex);
22401 IDirect3DDevice9_Release(device);
22402 IDirect3D9_Release(d3d9);
22403 DestroyWindow(window);
22404 return;
22407 hr = IDirect3DDevice9_CreateVertexBuffer(device, vertex_count * sizeof(*green_quad), 0,
22408 D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &vb, NULL);
22409 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
22411 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0,
22412 D3DFMT_INDEX16, D3DPOOL_MANAGED, &ib, NULL);
22413 ok(SUCCEEDED(hr), "Failed to create index buffer, hr %#x.\n", hr);
22415 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
22416 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
22417 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
22418 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
22419 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
22420 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
22422 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
22423 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
22425 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(green_quad), (void **)&vb_data, 0);
22426 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#x.\n", hr);
22427 vb_data[0] = green_quad[0];
22428 vb_data[1] = green_quad[1];
22429 vb_data[2] = green_quad[2];
22430 vb_data[0xffff] = green_quad[3];
22431 hr = IDirect3DVertexBuffer9_Unlock(vb);
22432 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#x.\n", hr);
22434 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), &data, 0);
22435 ok(hr == D3D_OK, "Failed to lock index buffer, hr %#x.\n", hr);
22436 memcpy(data, indices, sizeof(indices));
22437 hr = IDirect3DIndexBuffer9_Unlock(ib);
22438 ok(hr == D3D_OK, "Failed to unlock index buffer, hr %#x.\n", hr);
22440 hr = IDirect3DDevice9_SetIndices(device, ib);
22441 ok(hr == D3D_OK, "Failed to set index buffer, hr %#x.\n", hr);
22442 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(struct vertex));
22443 ok(hr == D3D_OK, "Failed to set stream source, hr %#x.\n", hr);
22445 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
22446 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22447 hr = IDirect3DDevice9_BeginScene(device);
22448 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22449 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 0, vertex_count, 0, 2);
22450 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22451 hr = IDirect3DDevice9_EndScene(device);
22452 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22453 color = getPixelColor(device, 20, 20);
22454 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
22455 color = getPixelColor(device, 320, 240);
22456 ok(color_match(color, 0x0000ff00, 1) || broken(warp), "Got unexpected color 0x%08x.\n", color);
22457 color = getPixelColor(device, 620, 460);
22458 ok(color_match(color, 0x0000ff00, 1) || broken(warp), "Got unexpected color 0x%08x.\n", color);
22460 IDirect3DIndexBuffer9_Release(ib);
22461 IDirect3DVertexBuffer9_Release(vb);
22462 refcount = IDirect3DDevice9_Release(device);
22463 ok(!refcount, "Device has %u references left.\n", refcount);
22464 IDirect3D9_Release(d3d9);
22465 DestroyWindow(window);
22468 static void test_backbuffer_resize(void)
22470 D3DPRESENT_PARAMETERS present_parameters = {0};
22471 IDirect3DSurface9 *backbuffer;
22472 IDirect3DDevice9 *device;
22473 IDirect3D9 *d3d;
22474 D3DCOLOR color;
22475 ULONG refcount;
22476 HWND window;
22477 HRESULT hr;
22479 static const struct
22481 struct vec3 position;
22482 DWORD diffuse;
22484 quad[] =
22486 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22487 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22488 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22489 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22492 window = create_window();
22493 d3d = Direct3DCreate9(D3D_SDK_VERSION);
22494 ok(!!d3d, "Failed to create a D3D object.\n");
22495 if (!(device = create_device(d3d, window, window, TRUE)))
22497 skip("Failed to create a D3D device.\n");
22498 goto done;
22501 /* Wine d3d9 implementation had a bug which was triggered by a
22502 * SetRenderTarget() call with an unreferenced surface. */
22503 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
22504 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
22505 refcount = IDirect3DSurface9_Release(backbuffer);
22506 ok(!refcount, "Surface has %u references left.\n", refcount);
22507 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
22508 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
22509 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
22510 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
22512 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
22513 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22514 color = getPixelColor(device, 1, 1);
22515 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
22517 present_parameters.BackBufferWidth = 800;
22518 present_parameters.BackBufferHeight = 600;
22519 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
22520 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
22521 present_parameters.hDeviceWindow = NULL;
22522 present_parameters.Windowed = TRUE;
22523 present_parameters.EnableAutoDepthStencil = TRUE;
22524 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
22525 hr = IDirect3DDevice9_Reset(device, &present_parameters);
22526 ok(SUCCEEDED(hr), "Failed to reset, hr %#x.\n", hr);
22528 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
22529 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
22530 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
22531 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
22532 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
22533 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
22534 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
22535 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
22537 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
22538 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
22539 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
22540 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
22541 IDirect3DSurface9_Release(backbuffer);
22543 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
22544 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22545 color = getPixelColor(device, 1, 1);
22546 ok(color == 0x00ffff00, "Got unexpected color 0x%08x.\n", color);
22547 color = getPixelColor(device, 700, 500);
22548 ok(color == 0x00ffff00, "Got unexpected color 0x%08x.\n", color);
22550 hr = IDirect3DDevice9_BeginScene(device);
22551 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22552 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
22553 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22554 hr = IDirect3DDevice9_EndScene(device);
22555 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22556 color = getPixelColor(device, 1, 1);
22557 ok(color == 0x0000ff00, "Got unexpected color 0x%08x.\n", color);
22558 color = getPixelColor(device, 700, 500);
22559 ok(color == 0x0000ff00, "Got unexpected color 0x%08x.\n", color);
22561 refcount = IDirect3DDevice9_Release(device);
22562 ok(!refcount, "Device has %u references left.\n", refcount);
22563 done:
22564 IDirect3D9_Release(d3d);
22565 DestroyWindow(window);
22568 static void test_drawindexedprimitiveup(void)
22570 static const struct vertex
22572 struct vec3 position;
22573 DWORD diffuse;
22575 quad[] =
22577 {{-1.0f, -1.0f, 0.1f}, 0xff00ff00},
22578 {{-1.0f, 1.0f, 0.1f}, 0xff0000ff},
22579 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
22580 {{ 1.0f, 1.0f, 0.1f}, 0xff0000ff},
22582 {{-1.0f, -1.0f, 0.1f}, 0xff0000ff},
22583 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
22584 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
22585 {{ 1.0f, 1.0f, 0.1f}, 0xff00ff00},
22587 static const unsigned short indices[] = {0, 1, 2, 3, 4, 5, 6, 7};
22588 IDirect3DDevice9 *device;
22589 IDirect3D9 *d3d;
22590 ULONG refcount;
22591 D3DCOLOR color;
22592 HWND window;
22593 HRESULT hr;
22595 window = create_window();
22596 d3d = Direct3DCreate9(D3D_SDK_VERSION);
22597 ok(!!d3d, "Failed to create a D3D object.\n");
22599 if (!(device = create_device(d3d, window, window, TRUE)))
22601 skip("Failed to create a D3D device.\n");
22602 IDirect3D9_Release(d3d);
22603 DestroyWindow(window);
22604 return;
22607 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
22608 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
22609 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
22610 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
22611 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
22612 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
22614 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
22615 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
22617 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
22618 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22620 hr = IDirect3DDevice9_BeginScene(device);
22621 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22622 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 4, 4, 2, indices + 4, D3DFMT_INDEX16, quad, sizeof(*quad));
22623 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22624 hr = IDirect3DDevice9_EndScene(device);
22625 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22627 color = getPixelColor(device, 160, 120);
22628 ok(color_match(color, 0x0040bf00, 1), "Got unexpected color 0x%08x.\n", color);
22629 color = getPixelColor(device, 480, 120);
22630 ok(color_match(color, 0x0040bf00, 1), "Got unexpected color 0x%08x.\n", color);
22631 color = getPixelColor(device, 160, 360);
22632 ok(color_match(color, 0x00404080, 1), "Got unexpected color 0x%08x.\n", color);
22633 color = getPixelColor(device, 480, 360);
22634 ok(color_match(color, 0x00bf4000, 1), "Got unexpected color 0x%08x.\n", color);
22636 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
22637 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22639 hr = IDirect3DDevice9_BeginScene(device);
22640 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22641 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 0, 4, 2, indices, D3DFMT_INDEX16, quad, sizeof(*quad));
22642 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22643 hr = IDirect3DDevice9_EndScene(device);
22644 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22646 color = getPixelColor(device, 160, 120);
22647 ok(color_match(color, 0x004000bf, 1), "Got unexpected color 0x%08x.\n", color);
22648 color = getPixelColor(device, 480, 120);
22649 ok(color_match(color, 0x004000bf, 1), "Got unexpected color 0x%08x.\n", color);
22650 color = getPixelColor(device, 160, 360);
22651 ok(color_match(color, 0x00408040, 1), "Got unexpected color 0x%08x.\n", color);
22652 color = getPixelColor(device, 480, 360);
22653 ok(color_match(color, 0x00bf0040, 1), "Got unexpected color 0x%08x.\n", color);
22655 refcount = IDirect3DDevice9_Release(device);
22656 ok(!refcount, "Device has %u references left.\n", refcount);
22657 IDirect3D9_Release(d3d);
22658 DestroyWindow(window);
22661 static void test_vertex_texture(void)
22663 static const D3DVERTEXELEMENT9 decl_elements[] =
22665 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
22666 D3DDECL_END()
22668 static const struct vec3 quad[] =
22670 {-1.0f, -1.0f, 0.0f},
22671 {-1.0f, 1.0f, 0.0f},
22672 { 1.0f, -1.0f, 0.0f},
22673 { 1.0f, 1.0f, 0.0f},
22675 static const DWORD vs_code[] =
22677 0xfffe0300, /* vs_3_0 */
22678 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0, 0, 0, 0 */
22679 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
22680 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
22681 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
22682 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
22683 0x0300005f, 0xe00f0001, 0xa0000000, 0xa0e40800, /* texldl o1, c0.x, s0 */
22684 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
22685 0x0000ffff, /* end */
22687 static const DWORD ps_code[] =
22689 0xffff0300, /* ps_3_0 */
22690 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color v0 */
22691 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
22692 0x0000ffff, /* end */
22694 static const DWORD texture_data[4] = {0x00ffff00, 0x00ffff00, 0x00ffff00, 0x00ffff00};
22695 IDirect3DVertexDeclaration9 *declaration;
22696 IDirect3DTexture9 *texture;
22697 IDirect3DVertexShader9 *vs;
22698 IDirect3DPixelShader9 *ps;
22699 IDirect3DDevice9 *device;
22700 D3DLOCKED_RECT lr;
22701 IDirect3D9 *d3d;
22702 D3DCOLOR color;
22703 ULONG refcount;
22704 D3DCAPS9 caps;
22705 HWND window;
22706 HRESULT hr;
22708 window = create_window();
22709 d3d = Direct3DCreate9(D3D_SDK_VERSION);
22710 ok(!!d3d, "Failed to create D3D object.\n");
22712 if (!(device = create_device(d3d, window, window, TRUE)))
22714 skip("Failed to create D3D device.\n");
22715 IDirect3D9_Release(d3d);
22716 DestroyWindow(window);
22717 return;
22720 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
22721 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
22722 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0) || caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
22724 skip("SM3 is not supported.\n");
22725 goto done;
22727 if (!(caps.VertexTextureFilterCaps & D3DPTFILTERCAPS_MAGFPOINT)
22728 || !(caps.VertexTextureFilterCaps & D3DPTFILTERCAPS_MINFPOINT))
22730 skip("Vertex texture point filtering is not supported, caps %#x.\n", caps.VertexTextureFilterCaps);
22731 goto done;
22733 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
22734 D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8);
22735 if (hr != D3D_OK)
22737 skip("No vertex texture fetch support for D3DFMT_A8R8G8B8, hr %#x.\n", hr);
22738 goto done;
22741 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
22742 ok(hr == D3D_OK, "Failed to create texture, hr %#x.\n", hr);
22743 memset(&lr, 0, sizeof(lr));
22744 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
22745 ok(hr == D3D_OK, "Failed to lock texture, hr %#x.\n", hr);
22746 memcpy(lr.pBits, texture_data, sizeof(texture_data));
22747 hr = IDirect3DTexture9_UnlockRect(texture, 0);
22748 ok(hr == D3D_OK, "Failed to unlock texture, hr %#x.\n", hr);
22750 hr = IDirect3DDevice9_SetTexture(device, D3DVERTEXTEXTURESAMPLER0, (IDirect3DBaseTexture9 *)texture);
22751 ok(hr == D3D_OK, "Failed to set texture, hr %#x.\n", hr);
22753 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &declaration);
22754 ok(SUCCEEDED(hr), "Failed to create vertex declaration, hr %#x.\n", hr);
22755 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
22756 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
22757 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
22758 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
22760 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration);
22761 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
22762 hr = IDirect3DDevice9_SetVertexShader(device, vs);
22763 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
22764 hr = IDirect3DDevice9_SetPixelShader(device, ps);
22765 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
22767 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
22768 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22769 hr = IDirect3DDevice9_BeginScene(device);
22770 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22771 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
22772 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22773 hr = IDirect3DDevice9_EndScene(device);
22774 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22775 color = getPixelColor(device, 160, 360);
22776 ok(color == texture_data[0], "Got unexpected color 0x%08x.\n", color);
22778 IDirect3DPixelShader9_Release(ps);
22779 IDirect3DVertexShader9_Release(vs);
22780 IDirect3DTexture9_Release(texture);
22781 IDirect3DVertexDeclaration9_Release(declaration);
22782 done:
22783 refcount = IDirect3DDevice9_Release(device);
22784 ok(!refcount, "Device has %u references left.\n", refcount);
22785 IDirect3D9_Release(d3d);
22786 DestroyWindow(window);
22789 static void test_mvp_software_vertex_shaders(void)
22791 IDirect3DVertexDeclaration9 *vertex_declaration;
22792 D3DPRESENT_PARAMETERS present_parameters = {0};
22793 IDirect3DVertexShader9 *pure_sw_shader = NULL;
22794 IDirect3DVertexShader9 *reladdr_shader = NULL;
22795 IDirect3DDevice9 *device;
22796 DWORD expected_color;
22797 IDirect3D9 *d3d;
22798 ULONG refcount;
22799 D3DCAPS9 caps;
22800 DWORD color;
22801 HWND window;
22802 HRESULT hr;
22804 static const float c_index[4] = {256.0f, 0.0f, 0.0f, 0.0f};
22805 static const float c_color[4] = {0.0f, 1.0f, 0.0f, 1.0f};
22806 static const DWORD reladdr_shader_code[] =
22808 0xfffe0200, /* vs_2_0 */
22809 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
22810 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c1, 1.0, 1.0, 1.0, 1.0 */
22811 0x0200002e, 0xb0010000, 0xa0000000, /* mova a0.x, c0.x */
22812 0x03000001, 0xd00f0000, 0xa0e42000, 0xb0000000, /* mov oD0, c[a0.x] */
22813 0x02000001, 0xd0040000, 0xa0e40001, /* mov oD0.z, c1 */
22814 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
22815 0x0000ffff /* END */
22817 static const DWORD pure_sw_shader_code[] =
22819 0xfffe0200, /* vs_2_0 */
22820 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
22821 0x05000051, 0xa00f0100, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c256, 1.0, 1.0, 1.0, 1.0 */
22822 0x02000001, 0xd00f0000, 0xa0e40100, /* mov oD0, c256 */
22823 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
22824 0x0000ffff /* END */
22827 static const struct
22829 float position[3];
22830 DWORD color;
22832 quad[] =
22834 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
22835 {{-1.0f, 1.0f, 0.0f}, 0xffff0000},
22836 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000},
22837 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
22839 static const D3DVERTEXELEMENT9 decl_elements[] =
22841 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
22842 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
22843 D3DDECL_END()
22846 window = create_window();
22847 d3d = Direct3DCreate9(D3D_SDK_VERSION);
22848 ok(!!d3d, "Failed to create a D3D object.\n");
22850 present_parameters.Windowed = TRUE;
22851 present_parameters.hDeviceWindow = window;
22852 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
22853 present_parameters.BackBufferWidth = 640;
22854 present_parameters.BackBufferHeight = 480;
22855 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
22856 present_parameters.EnableAutoDepthStencil = TRUE;
22857 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
22859 if (FAILED(IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
22860 D3DCREATE_MIXED_VERTEXPROCESSING, &present_parameters, &device)))
22862 skip("Failed to create a D3D device, skipping tests.\n");
22863 goto done;
22866 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
22867 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
22868 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
22870 skip("No vs_2_0 support, skipping tests.\n");
22871 IDirect3DDevice9_Release(device);
22872 goto done;
22875 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
22876 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
22878 hr = IDirect3DDevice9_SetSoftwareVertexProcessing(device, 0);
22879 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22881 hr = IDirect3DDevice9_CreateVertexShader(device, reladdr_shader_code, &reladdr_shader);
22882 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22883 hr = IDirect3DDevice9_CreateVertexShader(device, pure_sw_shader_code, &pure_sw_shader);
22884 todo_wine
22885 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22886 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
22887 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22888 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
22889 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22891 hr = IDirect3DDevice9_SetVertexShader(device, pure_sw_shader);
22892 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22894 hr = IDirect3DDevice9_BeginScene(device);
22895 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22896 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
22897 todo_wine
22898 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
22899 hr = IDirect3DDevice9_EndScene(device);
22900 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22902 expected_color = 0; /* Nothing rendered. */
22903 color = getPixelColor(device, 5, 5);
22904 todo_wine
22905 ok(color == expected_color, "Expected color 0x%08x, got 0x%08x (sw shader in hw mode).\n",
22906 expected_color, color);
22908 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
22909 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22910 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
22911 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22913 hr = IDirect3DDevice9_BeginScene(device);
22914 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22915 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
22916 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22917 hr = IDirect3DDevice9_EndScene(device);
22918 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22920 expected_color = 0x00ff0000; /* Color from vertex data and not from the shader. */
22921 color = getPixelColor(device, 5, 5);
22922 ok(color == expected_color, "Expected color 0x%08x, got 0x%08x (sw shader in hw mode, second attempt).\n",
22923 expected_color, color);
22925 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
22926 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22927 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
22928 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22930 hr = IDirect3DDevice9_BeginScene(device);
22931 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22932 hr = IDirect3DDevice9_SetSoftwareVertexProcessing(device, 1);
22933 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22934 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
22935 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22936 hr = IDirect3DDevice9_EndScene(device);
22937 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22939 expected_color = 0x00ffffff;
22940 color = getPixelColor(device, 5, 5);
22941 todo_wine
22942 ok(color == expected_color, "Expected color 0x%08x, got 0x%08x (sw shader in sw mode).\n",
22943 expected_color, color);
22945 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
22946 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22947 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
22948 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22950 hr = IDirect3DDevice9_SetSoftwareVertexProcessing(device, 0);
22951 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22952 hr = IDirect3DDevice9_SetVertexShader(device, reladdr_shader);
22953 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22955 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, c_index, 1);
22956 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22957 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, (unsigned int)c_index[0], c_color, 1);
22958 todo_wine
22959 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22961 hr = IDirect3DDevice9_BeginScene(device);
22962 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22963 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
22964 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22965 hr = IDirect3DDevice9_EndScene(device);
22966 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22968 /* Index 256 is out of bounds for selected shader in HW mode. c[256] is 0 most of the time. It
22969 is not guaranteed across all the adapters though, so disabling test. */
22970 #if 0
22971 expected_color = 0x000000ff;
22972 color = getPixelColor(device, 5, 5);
22973 ok(color == expected_color, "Expected color 0x%08x, got 0x%08x (shader in hw mode).\n",
22974 expected_color, color);
22975 #endif
22977 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
22978 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22979 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
22980 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22982 hr = IDirect3DDevice9_BeginScene(device);
22983 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22984 hr = IDirect3DDevice9_SetSoftwareVertexProcessing(device, 1);
22985 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
22986 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22987 hr = IDirect3DDevice9_EndScene(device);
22988 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22990 expected_color = 0x0000ffff; /* c[256] is c_color for SW shader. */
22991 color = getPixelColor(device, 5, 5);
22992 todo_wine
22993 ok(color == expected_color, "Expected color 0x%08x, got 0x%08x (shader in sw mode).\n",
22994 expected_color, color);
22996 IDirect3DVertexDeclaration9_Release(vertex_declaration);
22997 IDirect3DVertexShader9_Release(reladdr_shader);
22998 if (pure_sw_shader)
22999 IDirect3DVertexShader9_Release(pure_sw_shader);
23000 refcount = IDirect3DDevice9_Release(device);
23001 ok(!refcount, "Device has %u references left.\n", refcount);
23002 done:
23003 IDirect3D9_Release(d3d);
23004 DestroyWindow(window);
23007 static void test_null_format(void)
23009 static const D3DVIEWPORT9 vp_lower = {0, 60, 640, 420, 0.0f, 1.0f};
23010 static const D3DVIEWPORT9 vp_560 = {0, 180, 560, 300, 0.0f, 1.0f};
23011 static const D3DVIEWPORT9 vp_full = {0, 0, 640, 480, 0.0f, 1.0f};
23012 static const DWORD null_fourcc = MAKEFOURCC('N','U','L','L');
23013 static const struct
23015 struct vec3 pos;
23016 DWORD diffuse;
23018 quad_partial[] =
23020 {{-1.0f, 0.5f, 0.1f}, 0x000000ff},
23021 {{ 0.5f, 0.5f, 0.1f}, 0x000000ff},
23022 {{-1.0f, -1.0f, 0.1f}, 0x000000ff},
23023 {{ 0.5f, -1.0f, 0.1f}, 0x000000ff},
23025 quad[] =
23027 {{-1.0f, 1.0f, 0.5f}, 0x00ff0000},
23028 {{ 1.0f, 1.0f, 0.5f}, 0x00ff0000},
23029 {{-1.0f, -1.0f, 0.5f}, 0x00ff0000},
23030 {{ 1.0f, -1.0f, 0.5f}, 0x00ff0000},
23032 quad_far[] =
23034 {{-1.0f, 1.0f, 1.0f}, 0x0000ff00},
23035 {{ 1.0f, 1.0f, 1.0f}, 0x0000ff00},
23036 {{-1.0f, -1.0f, 1.0f}, 0x0000ff00},
23037 {{ 1.0f, -1.0f, 1.0f}, 0x0000ff00},
23039 static const struct
23041 unsigned int x, y;
23042 D3DCOLOR color;
23043 BOOL todo;
23045 expected_colors[] =
23047 {200, 30, 0x0000ff00, FALSE},
23048 {440, 30, 0x0000ff00, FALSE},
23049 {520, 30, 0x0000ff00, FALSE},
23050 {600, 30, 0x0000ff00, FALSE},
23051 {200, 90, 0x00000000, FALSE},
23052 {440, 90, 0x0000ff00, FALSE},
23053 {520, 90, 0x0000ff00, FALSE},
23054 {600, 90, 0x0000ff00, FALSE},
23055 {200, 150, 0x000000ff, FALSE},
23056 {440, 150, 0x000000ff, FALSE},
23057 {520, 150, 0x0000ff00, FALSE},
23058 {600, 150, 0x0000ff00, FALSE},
23059 {200, 320, 0x000000ff, FALSE},
23060 {440, 320, 0x000000ff, FALSE},
23061 {520, 320, 0x00000000, TRUE},
23062 {600, 320, 0x0000ff00, FALSE},
23064 IDirect3DSurface9 *original_rt, *small_rt, *null_rt, *small_null_rt;
23065 IDirect3DDevice9 *device;
23066 IDirect3D9 *d3d;
23067 unsigned int i;
23068 D3DCOLOR color;
23069 HWND window;
23070 HRESULT hr;
23072 d3d = Direct3DCreate9(D3D_SDK_VERSION);
23073 ok(!!d3d, "Failed to create a D3D object.\n");
23075 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
23076 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, null_fourcc)))
23078 skip("No NULL format support, skipping NULL test.\n");
23079 IDirect3D9_Release(d3d);
23080 return;
23083 window = create_window();
23084 if (!(device = create_device(d3d, window, window, TRUE)))
23086 skip("Failed to create a D3D device.\n");
23087 IDirect3D9_Release(d3d);
23088 DestroyWindow(window);
23089 return;
23092 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
23093 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
23095 hr = IDirect3DDevice9_CreateRenderTarget(device, 400, 300, D3DFMT_A8R8G8B8,
23096 D3DMULTISAMPLE_NONE, 0, FALSE, &small_rt, NULL);
23097 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
23098 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, null_fourcc,
23099 D3DMULTISAMPLE_NONE, 0, FALSE, &null_rt, NULL);
23100 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
23101 hr = IDirect3DDevice9_CreateRenderTarget(device, 400, 300, null_fourcc,
23102 D3DMULTISAMPLE_NONE, 0, FALSE, &small_null_rt, NULL);
23103 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
23105 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
23106 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
23107 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
23108 ok(SUCCEEDED(hr), "Failed to enable depth test, hr %#x.\n", hr);
23109 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
23110 ok(SUCCEEDED(hr), "Failed to set depth function, hr %#x.\n", hr);
23111 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
23112 ok(SUCCEEDED(hr), "Failed to enable depth write, hr %#x.\n", hr);
23113 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
23114 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
23116 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
23117 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
23119 /* Clear extends to viewport size > RT size even if format is not
23120 * "NULL". */
23121 hr = IDirect3DDevice9_SetRenderTarget(device, 0, small_rt);
23122 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
23124 hr = IDirect3DDevice9_SetViewport(device, &vp_full);
23125 ok(hr == D3D_OK, "Failed to set viewport, hr %#x.\n", hr);
23127 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.2f, 0);
23128 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
23130 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
23131 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
23133 hr = IDirect3DDevice9_BeginScene(device);
23134 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
23135 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
23136 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
23137 hr = IDirect3DDevice9_EndScene(device);
23138 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
23140 hr = IDirect3DDevice9_SetRenderTarget(device, 0, null_rt);
23141 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
23142 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
23143 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
23145 /* Draw only extends to viewport size > RT size if format is "NULL". */
23146 hr = IDirect3DDevice9_SetRenderTarget(device, 0, small_rt);
23147 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
23148 hr = IDirect3DDevice9_SetViewport(device, &vp_lower);
23149 ok(hr == D3D_OK, "Failed to set viewport, hr %#x.\n", hr);
23150 hr = IDirect3DDevice9_BeginScene(device);
23151 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
23152 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
23153 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
23154 hr = IDirect3DDevice9_EndScene(device);
23155 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
23157 hr = IDirect3DDevice9_SetRenderTarget(device, 0, small_null_rt);
23158 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
23159 hr = IDirect3DDevice9_SetViewport(device, &vp_560);
23160 ok(hr == D3D_OK, "Failed to set viewport, hr %#x.\n", hr);
23161 hr = IDirect3DDevice9_BeginScene(device);
23162 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
23163 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
23164 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
23165 hr = IDirect3DDevice9_EndScene(device);
23166 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
23168 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
23169 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
23171 hr = IDirect3DDevice9_BeginScene(device);
23172 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
23173 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_partial, sizeof(*quad_partial));
23174 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
23175 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_far, sizeof(*quad_far));
23176 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
23177 hr = IDirect3DDevice9_EndScene(device);
23178 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
23180 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
23182 color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
23183 todo_wine_if(expected_colors[i].todo) ok(color_match(color, expected_colors[i].color, 1),
23184 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
23185 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
23188 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
23189 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
23191 IDirect3DSurface9_Release(small_null_rt);
23192 IDirect3DSurface9_Release(null_rt);
23193 IDirect3DSurface9_Release(small_rt);
23194 IDirect3DSurface9_Release(original_rt);
23195 cleanup_device(device);
23196 IDirect3D9_Release(d3d);
23199 static void test_map_synchronisation(void)
23201 LARGE_INTEGER frequency, diff, ts[3];
23202 unsigned int i, j, tri_count, size;
23203 D3DADAPTER_IDENTIFIER9 identifier;
23204 IDirect3DVertexBuffer9 *buffer;
23205 IDirect3DDevice9 *device;
23206 BOOL unsynchronised, ret;
23207 IDirect3D9 *d3d;
23208 D3DCOLOR colour;
23209 ULONG refcount;
23210 D3DCAPS9 caps;
23211 HWND window;
23212 HRESULT hr;
23214 static const struct
23216 unsigned int flags;
23217 BOOL unsynchronised;
23219 tests[] =
23221 {0, FALSE},
23222 {D3DLOCK_NOOVERWRITE, TRUE},
23223 {D3DLOCK_DISCARD, FALSE},
23224 {D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD, TRUE},
23227 static const struct quad
23229 struct
23231 struct vec3 position;
23232 DWORD diffuse;
23233 } strip[4];
23235 quad1 =
23238 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
23239 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
23240 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
23241 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
23244 quad2 =
23247 {{-1.0f, -1.0f, 0.0f}, 0xffffff00},
23248 {{-1.0f, 1.0f, 0.0f}, 0xffffff00},
23249 {{ 1.0f, -1.0f, 0.0f}, 0xffffff00},
23250 {{ 1.0f, 1.0f, 0.0f}, 0xffffff00},
23253 struct quad *quads;
23255 window = create_window();
23256 ok(!!window, "Failed to create a window.\n");
23258 d3d = Direct3DCreate9(D3D_SDK_VERSION);
23259 ok(!!d3d, "Failed to create a D3D object.\n");
23260 if (!(device = create_device(d3d, window, window, TRUE)))
23262 skip("Failed to create a D3D device, skipping tests.\n");
23263 IDirect3D9_Release(d3d);
23264 DestroyWindow(window);
23265 return;
23268 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
23269 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
23270 /* Maps are always synchronised on WARP. */
23271 if (adapter_is_warp(&identifier))
23273 skip("Running on WARP, skipping test.\n");
23274 goto done;
23277 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
23278 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
23280 tri_count = 0x1000;
23281 if (tri_count > caps.MaxPrimitiveCount)
23283 skip("Device supports only %u primitives, skipping test.\n", caps.MaxPrimitiveCount);
23284 goto done;
23286 size = (tri_count + 2) * sizeof(*quad1.strip);
23288 ret = QueryPerformanceFrequency(&frequency);
23289 ok(ret, "Failed to get performance counter frequency.\n");
23291 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
23292 D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &buffer, NULL);
23293 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
23294 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, size, (void **)&quads, D3DLOCK_DISCARD);
23295 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
23296 for (j = 0; j < size / sizeof(*quads); ++j)
23298 quads[j] = quad1;
23300 hr = IDirect3DVertexBuffer9_Unlock(buffer);
23301 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
23303 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
23304 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
23305 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
23306 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
23307 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(*quads->strip));
23308 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
23310 /* Initial draw to initialise states, compile shaders, etc. */
23311 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
23312 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
23313 hr = IDirect3DDevice9_BeginScene(device);
23314 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
23315 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, tri_count);
23316 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
23317 hr = IDirect3DDevice9_EndScene(device);
23318 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
23319 /* Read the result to ensure the GPU has finished drawing. */
23320 colour = getPixelColor(device, 320, 240);
23322 /* Time drawing tri_count triangles. */
23323 ret = QueryPerformanceCounter(&ts[0]);
23324 ok(ret, "Failed to read performance counter.\n");
23325 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
23326 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
23327 hr = IDirect3DDevice9_BeginScene(device);
23328 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
23329 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, tri_count);
23330 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
23331 hr = IDirect3DDevice9_EndScene(device);
23332 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
23333 colour = getPixelColor(device, 320, 240);
23334 /* Time drawing a single triangle. */
23335 ret = QueryPerformanceCounter(&ts[1]);
23336 ok(ret, "Failed to read performance counter.\n");
23337 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
23338 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
23339 hr = IDirect3DDevice9_BeginScene(device);
23340 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
23341 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 1);
23342 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
23343 hr = IDirect3DDevice9_EndScene(device);
23344 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
23345 colour = getPixelColor(device, 320, 240);
23346 ret = QueryPerformanceCounter(&ts[2]);
23347 ok(ret, "Failed to read performance counter.\n");
23349 IDirect3DVertexBuffer9_Release(buffer);
23351 /* Estimate the number of triangles we can draw in 100ms. */
23352 diff.QuadPart = ts[1].QuadPart - ts[0].QuadPart + ts[1].QuadPart - ts[2].QuadPart;
23353 tri_count = (tri_count * frequency.QuadPart) / (diff.QuadPart * 10);
23354 tri_count = ((tri_count + 2 + 3) & ~3) - 2;
23355 if (tri_count > caps.MaxPrimitiveCount)
23357 skip("Would need to draw %u triangles, but the device only supports %u primitives.\n",
23358 tri_count, caps.MaxPrimitiveCount);
23359 goto done;
23361 size = (tri_count + 2) * sizeof(*quad1.strip);
23363 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
23365 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
23366 D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &buffer, NULL);
23367 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
23368 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, size, (void **)&quads, D3DLOCK_DISCARD);
23369 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
23370 for (j = 0; j < size / sizeof(*quads); ++j)
23372 quads[j] = quad1;
23374 hr = IDirect3DVertexBuffer9_Unlock(buffer);
23375 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
23377 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(*quads->strip));
23378 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
23380 /* Start a draw operation. */
23381 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
23382 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
23383 hr = IDirect3DDevice9_BeginScene(device);
23384 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
23385 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, tri_count);
23386 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
23387 hr = IDirect3DDevice9_EndScene(device);
23388 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
23390 /* Map the last quad while the draw is in progress. */
23391 hr = IDirect3DVertexBuffer9_Lock(buffer, size - sizeof(quad2),
23392 sizeof(quad2), (void **)&quads, tests[i].flags);
23393 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
23394 *quads = quad2;
23395 hr = IDirect3DVertexBuffer9_Unlock(buffer);
23396 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
23398 colour = getPixelColor(device, 320, 240);
23399 unsynchronised = color_match(colour, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1);
23400 ok(tests[i].unsynchronised == unsynchronised, "Expected %s map for flags %#x.\n",
23401 tests[i].unsynchronised ? "unsynchronised" : "synchronised", tests[i].flags);
23403 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
23404 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
23406 IDirect3DVertexBuffer9_Release(buffer);
23409 done:
23410 refcount = IDirect3DDevice9_Release(device);
23411 ok(!refcount, "Device has %u references left.\n", refcount);
23412 IDirect3D9_Release(d3d);
23413 DestroyWindow(window);
23416 START_TEST(visual)
23418 D3DADAPTER_IDENTIFIER9 identifier;
23419 IDirect3D9 *d3d;
23420 HRESULT hr;
23422 if (!(d3d = Direct3DCreate9(D3D_SDK_VERSION)))
23424 skip("could not create D3D9 object\n");
23425 return;
23428 memset(&identifier, 0, sizeof(identifier));
23429 hr = IDirect3D9_GetAdapterIdentifier(d3d, 0, 0, &identifier);
23430 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
23431 trace("Driver string: \"%s\"\n", identifier.Driver);
23432 trace("Description string: \"%s\"\n", identifier.Description);
23433 /* Only Windows XP's default VGA driver should have an empty description */
23434 ok(identifier.Description[0] || broken(!strcmp(identifier.Driver, "vga.dll")), "Empty driver description.\n");
23435 trace("Device name string: \"%s\"\n", identifier.DeviceName);
23436 ok(identifier.DeviceName[0], "Empty device name.\n");
23437 trace("Driver version %d.%d.%d.%d\n",
23438 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
23439 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
23441 IDirect3D9_Release(d3d);
23443 test_sanity();
23444 depth_clamp_test();
23445 stretchrect_test();
23446 lighting_test();
23447 test_specular_lighting();
23448 clear_test();
23449 color_fill_test();
23450 fog_test();
23451 test_cube_wrap();
23452 z_range_test();
23453 maxmip_test();
23454 offscreen_test();
23455 ds_size_test();
23456 test_blend();
23457 test_shademode();
23458 srgbtexture_test();
23459 release_buffer_test();
23460 float_texture_test();
23461 g16r16_texture_test();
23462 pixelshader_blending_test();
23463 texture_transform_flags_test();
23464 test_mipmap_autogen();
23465 fixed_function_decl_test();
23466 conditional_np2_repeat_test();
23467 fixed_function_bumpmap_test();
23468 test_pointsize();
23469 tssargtemp_test();
23470 np2_stretch_rect_test();
23471 yuv_color_test();
23472 yuv_layout_test();
23473 zwriteenable_test();
23474 alphatest_test();
23475 viewport_test();
23476 test_constant_clamp_vs();
23477 test_compare_instructions();
23478 test_mova();
23479 loop_index_test();
23480 sincos_test();
23481 sgn_test();
23482 clip_planes_test();
23483 test_vshader_input();
23484 test_vshader_float16();
23485 stream_test();
23486 fog_with_shader_test();
23487 texbem_test();
23488 texdepth_test();
23489 texkill_test();
23490 volume_v16u16_test();
23491 constant_clamp_ps_test();
23492 cnd_test();
23493 dp2add_ps_test();
23494 unbound_sampler_test();
23495 nested_loop_test();
23496 pretransformed_varying_test();
23497 vface_register_test();
23498 test_fragment_coords();
23499 multiple_rendertargets_test();
23500 texop_test();
23501 texop_range_test();
23502 alphareplicate_test();
23503 dp3_alpha_test();
23504 depth_buffer_test();
23505 depth_buffer2_test();
23506 depth_blit_test();
23507 intz_test();
23508 shadow_test();
23509 fp_special_test();
23510 depth_bounds_test();
23511 srgbwrite_format_test();
23512 update_surface_test();
23513 multisample_get_rtdata_test();
23514 zenable_test();
23515 fog_special_test();
23516 volume_srgb_test();
23517 volume_dxt5_test();
23518 add_dirty_rect_test();
23519 multisampled_depth_buffer_test();
23520 resz_test();
23521 stencil_cull_test();
23522 test_per_stage_constant();
23523 test_3dc_formats();
23524 test_fog_interpolation();
23525 test_negative_fixedfunction_fog();
23526 test_position_index();
23527 test_table_fog_zw();
23528 test_signed_formats();
23529 test_multisample_mismatch();
23530 test_texcoordindex();
23531 test_vertex_blending();
23532 test_updatetexture();
23533 test_depthbias();
23534 test_flip();
23535 test_uninitialized_varyings();
23536 test_multisample_init();
23537 test_texture_blending();
23538 test_color_clamping();
23539 test_line_antialiasing_blending();
23540 test_dsy();
23541 test_evict_bound_resources();
23542 test_max_index16();
23543 test_backbuffer_resize();
23544 test_drawindexedprimitiveup();
23545 test_vertex_texture();
23546 test_mvp_software_vertex_shaders();
23547 test_null_format();
23548 test_map_synchronisation();