d3d9/tests: Skip test_vshader_input() if PS 3.0 isn't supported.
[wine.git] / dlls / d3d9 / tests / visual.c
blobe012d1b2b09138ea0b9c7edc661f148342bd5bfe
1 /*
2 * Copyright 2005, 2007-2008 Henri Verbeet
3 * Copyright (C) 2007-2013 Stefan Dösinger(for CodeWeavers)
4 * Copyright (C) 2008 Jason Green(for TransGaming)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 /* This test framework allows limited testing of rendering results. Things are rendered, shown on
22 * the framebuffer, read back from there and compared to expected colors.
24 * However, neither d3d nor opengl is guaranteed to be pixel exact, and thus the capability of this test
25 * is rather limited. As a general guideline for adding tests, do not rely on corner pixels. Draw a big enough
26 * area which shows specific behavior(like a quad on the whole screen), and try to get resulting colors with
27 * all bits set or unset in all channels(like pure red, green, blue, white, black). Hopefully everything that
28 * causes visible results in games can be tested in a way that does not depend on pixel exactness
31 #include <math.h>
33 #define COBJMACROS
34 #include <d3d9.h>
35 #include "wine/test.h"
37 struct vec2
39 float x, y;
42 struct vec3
44 float x, y, z;
47 struct vec4
49 float x, y, z, w;
52 static HWND create_window(void)
54 HWND hwnd;
55 RECT rect;
57 SetRect(&rect, 0, 0, 640, 480);
58 AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE);
59 hwnd = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
60 0, 0, rect.right - rect.left, rect.bottom - rect.top, 0, 0, 0, 0);
61 return hwnd;
64 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
66 if (abs((int)(c1 & 0xff) - (int)(c2 & 0xff)) > max_diff) return FALSE;
67 c1 >>= 8; c2 >>= 8;
68 if (abs((int)(c1 & 0xff) - (int)(c2 & 0xff)) > max_diff) return FALSE;
69 c1 >>= 8; c2 >>= 8;
70 if (abs((int)(c1 & 0xff) - (int)(c2 & 0xff)) > max_diff) return FALSE;
71 c1 >>= 8; c2 >>= 8;
72 if (abs((int)(c1 & 0xff) - (int)(c2 & 0xff)) > max_diff) return FALSE;
73 return TRUE;
76 static BOOL adapter_is_warp(const D3DADAPTER_IDENTIFIER9 *identifier)
78 return !strcmp(identifier->Driver, "d3d10warp.dll");
81 /* Locks a given surface and returns the color at (x,y). It's the caller's
82 * responsibility to only pass in lockable surfaces and valid x,y coordinates */
83 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
85 DWORD color;
86 HRESULT hr;
87 D3DSURFACE_DESC desc;
88 RECT rectToLock = {x, y, x+1, y+1};
89 D3DLOCKED_RECT lockedRect;
91 hr = IDirect3DSurface9_GetDesc(surface, &desc);
92 if(FAILED(hr)) /* This is not a test */
94 trace("Can't get the surface description, hr=%08x\n", hr);
95 return 0xdeadbeef;
98 hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
99 if(FAILED(hr)) /* This is not a test */
101 trace("Can't lock the surface, hr=%08x\n", hr);
102 return 0xdeadbeef;
104 switch(desc.Format) {
105 case D3DFMT_A8R8G8B8:
107 color = ((DWORD *) lockedRect.pBits)[0];
108 break;
110 default:
111 trace("Error: unknown surface format: %d\n", desc.Format);
112 color = 0xdeadbeef;
113 break;
115 hr = IDirect3DSurface9_UnlockRect(surface);
116 if(FAILED(hr))
118 trace("Can't unlock the surface, hr=%08x\n", hr);
120 return color;
123 struct surface_readback
125 IDirect3DSurface9 *surface;
126 D3DLOCKED_RECT locked_rect;
129 static void get_rt_readback(IDirect3DSurface9 *surface, struct surface_readback *rb)
131 IDirect3DDevice9 *device;
132 D3DSURFACE_DESC desc;
133 HRESULT hr;
135 memset(rb, 0, sizeof(*rb));
136 hr = IDirect3DSurface9_GetDevice(surface, &device);
137 ok(SUCCEEDED(hr), "Failed to get device, hr %#x.\n", hr);
138 hr = IDirect3DSurface9_GetDesc(surface, &desc);
139 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
140 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, desc.Width, desc.Height,
141 desc.Format, D3DPOOL_SYSTEMMEM, &rb->surface, NULL);
142 if (FAILED(hr) || !rb->surface)
144 trace("Can't create an offscreen plain surface to read the render target data, hr %#x.\n", hr);
145 goto error;
148 hr = IDirect3DDevice9_GetRenderTargetData(device, surface, rb->surface);
149 if (FAILED(hr))
151 trace("Can't read the render target data, hr %#x.\n", hr);
152 goto error;
155 hr = IDirect3DSurface9_LockRect(rb->surface, &rb->locked_rect, NULL, D3DLOCK_READONLY);
156 if (FAILED(hr))
158 trace("Can't lock the offscreen surface, hr %#x.\n", hr);
159 goto error;
161 IDirect3DDevice9_Release(device);
163 return;
165 error:
166 if (rb->surface)
167 IDirect3DSurface9_Release(rb->surface);
168 rb->surface = NULL;
169 IDirect3DDevice9_Release(device);
172 static DWORD get_readback_color(struct surface_readback *rb, unsigned int x, unsigned int y)
174 return rb->locked_rect.pBits
175 ? ((DWORD *)rb->locked_rect.pBits)[y * rb->locked_rect.Pitch / sizeof(DWORD) + x] : 0xdeadbeef;
178 static void release_surface_readback(struct surface_readback *rb)
180 HRESULT hr;
182 if (!rb->surface)
183 return;
184 if (rb->locked_rect.pBits && FAILED(hr = IDirect3DSurface9_UnlockRect(rb->surface)))
185 trace("Can't unlock the offscreen surface, hr %#x.\n", hr);
186 IDirect3DSurface9_Release(rb->surface);
189 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
191 DWORD ret;
192 IDirect3DSurface9 *rt;
193 struct surface_readback rb;
194 HRESULT hr;
196 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
197 if(FAILED(hr))
199 trace("Can't get the render target, hr %#x.\n", hr);
200 return 0xdeadbeed;
203 get_rt_readback(rt, &rb);
204 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
205 * really important for these tests
207 ret = get_readback_color(&rb, x, y) & 0x00ffffff;
208 release_surface_readback(&rb);
210 IDirect3DSurface9_Release(rt);
211 return ret;
214 static IDirect3DDevice9 *create_device(IDirect3D9 *d3d, HWND device_window, HWND focus_window, BOOL windowed)
216 D3DPRESENT_PARAMETERS present_parameters = {0};
217 IDirect3DDevice9 *device;
219 present_parameters.Windowed = windowed;
220 present_parameters.hDeviceWindow = device_window;
221 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
222 present_parameters.BackBufferWidth = 640;
223 present_parameters.BackBufferHeight = 480;
224 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
225 present_parameters.EnableAutoDepthStencil = TRUE;
226 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
228 if (SUCCEEDED(IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
229 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device)))
230 return device;
232 return NULL;
235 static void cleanup_device(IDirect3DDevice9 *device)
237 if (device)
239 D3DPRESENT_PARAMETERS present_parameters;
240 IDirect3DSwapChain9 *swapchain;
241 ULONG ref;
243 IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
244 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
245 IDirect3DSwapChain9_Release(swapchain);
246 ref = IDirect3DDevice9_Release(device);
247 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
248 DestroyWindow(present_parameters.hDeviceWindow);
252 static void test_sanity(void)
254 IDirect3DDevice9 *device;
255 IDirect3D9 *d3d;
256 D3DCOLOR color;
257 ULONG refcount;
258 HWND window;
259 HRESULT hr;
261 window = create_window();
262 d3d = Direct3DCreate9(D3D_SDK_VERSION);
263 ok(!!d3d, "Failed to create a D3D object.\n");
264 if (!(device = create_device(d3d, window, window, TRUE)))
266 skip("Failed to create a D3D device, skipping tests.\n");
267 goto done;
270 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
271 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
272 color = getPixelColor(device, 1, 1);
273 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
275 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
276 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
278 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
279 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
280 color = getPixelColor(device, 639, 479);
281 ok(color == 0x0000ddee, "Got unexpected color 0x%08x.\n", color);
283 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
284 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
286 refcount = IDirect3DDevice9_Release(device);
287 ok(!refcount, "Device has %u references left.\n", refcount);
288 done:
289 IDirect3D9_Release(d3d);
290 DestroyWindow(window);
293 static void lighting_test(void)
295 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
296 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
297 IDirect3DDevice9 *device;
298 D3DMATERIAL9 material;
299 IDirect3D9 *d3d;
300 D3DCOLOR color;
301 ULONG refcount;
302 HWND window;
303 HRESULT hr;
304 unsigned int i;
306 static const D3DMATRIX mat =
308 1.0f, 0.0f, 0.0f, 0.0f,
309 0.0f, 1.0f, 0.0f, 0.0f,
310 0.0f, 0.0f, 1.0f, 0.0f,
311 0.0f, 0.0f, 0.0f, 1.0f,
312 }}},
313 mat_singular =
315 1.0f, 0.0f, 1.0f, 0.0f,
316 0.0f, 1.0f, 0.0f, 0.0f,
317 1.0f, 0.0f, 1.0f, 0.0f,
318 0.0f, 0.0f, 0.5f, 1.0f,
319 }}},
320 mat_transf =
322 0.0f, 0.0f, 1.0f, 0.0f,
323 0.0f, 1.0f, 0.0f, 0.0f,
324 -1.0f, 0.0f, 0.0f, 0.0f,
325 10.f, 10.0f, 10.0f, 1.0f,
326 }}},
327 mat_nonaffine =
329 1.0f, 0.0f, 0.0f, 0.0f,
330 0.0f, 1.0f, 0.0f, 0.0f,
331 0.0f, 0.0f, 1.0f, -1.0f,
332 10.f, 10.0f, 10.0f, 0.0f,
333 }}};
334 static const struct
336 struct vec3 position;
337 DWORD diffuse;
339 unlitquad[] =
341 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
342 {{-1.0f, 0.0f, 0.1f}, 0xffff0000},
343 {{ 0.0f, 0.0f, 0.1f}, 0xffff0000},
344 {{ 0.0f, -1.0f, 0.1f}, 0xffff0000},
346 litquad[] =
348 {{-1.0f, 0.0f, 0.1f}, 0xff00ff00},
349 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
350 {{ 0.0f, 1.0f, 0.1f}, 0xff00ff00},
351 {{ 0.0f, 0.0f, 0.1f}, 0xff00ff00},
353 lighting_test[] =
355 {{-1.0f, -1.0f, 0.1f}, 0x8000ff00},
356 {{ 1.0f, -1.0f, 0.1f}, 0x80000000},
357 {{-1.0f, 1.0f, 0.1f}, 0x8000ff00},
358 {{ 1.0f, 1.0f, 0.1f}, 0x80000000},
360 static const struct
362 struct vec3 position;
363 struct vec3 normal;
364 DWORD diffuse;
366 unlitnquad[] =
368 {{0.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
369 {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
370 {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
371 {{1.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
373 litnquad[] =
375 {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
376 {{0.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
377 {{1.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
378 {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
380 nquad[] =
382 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
383 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
384 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
385 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
387 rotatedquad[] =
389 {{-10.0f, -11.0f, 11.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
390 {{-10.0f, -9.0f, 11.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
391 {{-10.0f, -9.0f, 9.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
392 {{-10.0f, -11.0f, 9.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
394 translatedquad[] =
396 {{-11.0f, -11.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
397 {{-11.0f, -9.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
398 {{ -9.0f, -9.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
399 {{ -9.0f, -11.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
401 static const WORD indices[] = {0, 1, 2, 2, 3, 0};
402 static const struct
404 const D3DMATRIX *world_matrix;
405 const void *quad;
406 unsigned int size;
407 DWORD expected;
408 const char *message;
410 tests[] =
412 {&mat, nquad, sizeof(nquad[0]), 0x000000ff, "Lit quad with light"},
413 {&mat_singular, nquad, sizeof(nquad[0]), 0x000000ff, "Lit quad with singular world matrix"},
414 {&mat_transf, rotatedquad, sizeof(rotatedquad[0]), 0x000000ff, "Lit quad with transformation matrix"},
415 {&mat_nonaffine, translatedquad, sizeof(translatedquad[0]), 0x00000000, "Lit quad with non-affine matrix"},
418 window = create_window();
419 d3d = Direct3DCreate9(D3D_SDK_VERSION);
420 ok(!!d3d, "Failed to create a D3D object.\n");
421 if (!(device = create_device(d3d, window, window, TRUE)))
423 skip("Failed to create a D3D device, skipping tests.\n");
424 goto done;
427 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
428 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
430 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &mat);
431 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
432 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
433 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
434 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
435 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
436 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
437 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
438 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
439 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
440 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
441 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
442 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
443 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
444 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
445 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
447 hr = IDirect3DDevice9_SetFVF(device, fvf);
448 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
450 hr = IDirect3DDevice9_BeginScene(device);
451 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
453 /* No lights are defined... That means, lit vertices should be entirely black */
454 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
455 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
456 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
457 2, indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
458 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
460 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
461 ok(SUCCEEDED(hr), "Failed to enable lighting, hr %#x.\n", hr);
462 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
463 2, indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
464 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
466 hr = IDirect3DDevice9_SetFVF(device, nfvf);
467 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
469 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
470 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
471 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
472 2, indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
473 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
475 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
476 ok(SUCCEEDED(hr), "Failed to enable lighting, hr %#x.\n", hr);
477 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
478 2, indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
479 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
481 hr = IDirect3DDevice9_EndScene(device);
482 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
484 color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
485 ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
486 color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
487 ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
488 color = getPixelColor(device, 480, 360); /* Lower left quad - unlit with normals */
489 ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
490 color = getPixelColor(device, 480, 120); /* Upper left quad - lit with normals */
491 ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
493 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
495 hr = IDirect3DDevice9_LightEnable(device, 0, TRUE);
496 ok(SUCCEEDED(hr), "Failed to enable light 0, hr %#x.\n", hr);
498 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
500 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, tests[i].world_matrix);
501 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
503 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
504 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
506 hr = IDirect3DDevice9_BeginScene(device);
507 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
509 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
510 2, indices, D3DFMT_INDEX16, tests[i].quad, tests[i].size);
511 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
513 hr = IDirect3DDevice9_EndScene(device);
514 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
516 color = getPixelColor(device, 320, 240);
517 ok(color == tests[i].expected, "%s has color 0x%08x.\n", tests[i].message, color);
520 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
521 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
522 hr = IDirect3DDevice9_LightEnable(device, 0, FALSE);
523 ok(SUCCEEDED(hr), "Failed to disable light 0, hr %#x.\n", hr);
525 memset(&material, 0, sizeof(material));
526 material.Diffuse.r = 0.0;
527 material.Diffuse.g = 0.0;
528 material.Diffuse.b = 0.0;
529 material.Diffuse.a = 1.0;
530 material.Ambient.r = 0.0;
531 material.Ambient.g = 0.0;
532 material.Ambient.b = 0.0;
533 material.Ambient.a = 0.0;
534 material.Specular.r = 0.0;
535 material.Specular.g = 0.0;
536 material.Specular.b = 0.0;
537 material.Specular.a = 0.0;
538 material.Emissive.r = 0.0;
539 material.Emissive.g = 0.0;
540 material.Emissive.b = 0.0;
541 material.Emissive.a = 0.0;
542 material.Power = 0.0;
543 hr = IDirect3DDevice9_SetMaterial(device, &material);
544 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
546 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
547 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
548 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
549 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
551 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
552 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
553 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
554 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
556 hr = IDirect3DDevice9_BeginScene(device);
557 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
559 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
560 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
561 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
562 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
564 hr = IDirect3DDevice9_EndScene(device);
565 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
567 color = getPixelColor(device, 320, 240);
568 ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
569 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
571 refcount = IDirect3DDevice9_Release(device);
572 ok(!refcount, "Device has %u references left.\n", refcount);
573 done:
574 IDirect3D9_Release(d3d);
575 DestroyWindow(window);
578 static void test_specular_lighting(void)
580 static const unsigned int vertices_side = 5;
581 const unsigned int indices_count = (vertices_side - 1) * (vertices_side - 1) * 2 * 3;
582 static const DWORD fvf = D3DFVF_XYZ | D3DFVF_NORMAL;
583 static const D3DMATRIX mat =
585 1.0f, 0.0f, 0.0f, 0.0f,
586 0.0f, 1.0f, 0.0f, 0.0f,
587 0.0f, 0.0f, 1.0f, 0.0f,
588 0.0f, 0.0f, 0.0f, 1.0f,
589 }}};
590 static const D3DLIGHT9 directional =
592 D3DLIGHT_DIRECTIONAL,
593 {0.0f, 0.0f, 0.0f, 0.0f},
594 {1.0f, 1.0f, 1.0f, 0.0f},
595 {0.0f, 0.0f, 0.0f, 0.0f},
596 {0.0f, 0.0f, 0.0f},
597 {0.0f, 0.0f, 1.0f},
599 point =
601 D3DLIGHT_POINT,
602 {0.0f, 0.0f, 0.0f, 0.0f},
603 {1.0f, 1.0f, 1.0f, 0.0f},
604 {0.0f, 0.0f, 0.0f, 0.0f},
605 {0.0f, 0.0f, 0.0f},
606 {0.0f, 0.0f, 0.0f},
607 100.0f,
608 0.0f,
609 0.0f, 0.0f, 1.0f,
611 spot =
613 D3DLIGHT_SPOT,
614 {0.0f, 0.0f, 0.0f, 0.0f},
615 {1.0f, 1.0f, 1.0f, 0.0f},
616 {0.0f, 0.0f, 0.0f, 0.0f},
617 {0.0f, 0.0f, 0.0f},
618 {0.0f, 0.0f, 1.0f},
619 100.0f,
620 1.0f,
621 0.0f, 0.0f, 1.0f,
622 M_PI / 12.0f, M_PI / 3.0f
624 /* The chosen range value makes the test fail when using a manhattan
625 * distance metric vs the correct euclidean distance. */
626 point_range =
628 D3DLIGHT_POINT,
629 {0.0f, 0.0f, 0.0f, 0.0f},
630 {1.0f, 1.0f, 1.0f, 0.0f},
631 {0.0f, 0.0f, 0.0f, 0.0f},
632 {0.0f, 0.0f, 0.0f},
633 {0.0f, 0.0f, 0.0f},
634 1.2f,
635 0.0f,
636 0.0f, 0.0f, 1.0f,
638 static const struct expected_color
640 unsigned int x, y;
641 D3DCOLOR color;
643 expected_directional[] =
645 {160, 120, 0x00ffffff},
646 {320, 120, 0x00ffffff},
647 {480, 120, 0x00ffffff},
648 {160, 240, 0x00ffffff},
649 {320, 240, 0x00ffffff},
650 {480, 240, 0x00ffffff},
651 {160, 360, 0x00ffffff},
652 {320, 360, 0x00ffffff},
653 {480, 360, 0x00ffffff},
655 expected_directional_local[] =
657 {160, 120, 0x003c3c3c},
658 {320, 120, 0x00717171},
659 {480, 120, 0x003c3c3c},
660 {160, 240, 0x00717171},
661 {320, 240, 0x00ffffff},
662 {480, 240, 0x00717171},
663 {160, 360, 0x003c3c3c},
664 {320, 360, 0x00717171},
665 {480, 360, 0x003c3c3c},
667 expected_point[] =
669 {160, 120, 0x00282828},
670 {320, 120, 0x005a5a5a},
671 {480, 120, 0x00282828},
672 {160, 240, 0x005a5a5a},
673 {320, 240, 0x00ffffff},
674 {480, 240, 0x005a5a5a},
675 {160, 360, 0x00282828},
676 {320, 360, 0x005a5a5a},
677 {480, 360, 0x00282828},
679 expected_point_local[] =
681 {160, 120, 0x00000000},
682 {320, 120, 0x00070707},
683 {480, 120, 0x00000000},
684 {160, 240, 0x00070707},
685 {320, 240, 0x00ffffff},
686 {480, 240, 0x00070707},
687 {160, 360, 0x00000000},
688 {320, 360, 0x00070707},
689 {480, 360, 0x00000000},
691 expected_spot[] =
693 {160, 120, 0x00000000},
694 {320, 120, 0x00141414},
695 {480, 120, 0x00000000},
696 {160, 240, 0x00141414},
697 {320, 240, 0x00ffffff},
698 {480, 240, 0x00141414},
699 {160, 360, 0x00000000},
700 {320, 360, 0x00141414},
701 {480, 360, 0x00000000},
703 expected_spot_local[] =
705 {160, 120, 0x00000000},
706 {320, 120, 0x00020202},
707 {480, 120, 0x00000000},
708 {160, 240, 0x00020202},
709 {320, 240, 0x00ffffff},
710 {480, 240, 0x00020202},
711 {160, 360, 0x00000000},
712 {320, 360, 0x00020202},
713 {480, 360, 0x00000000},
715 expected_point_range[] =
717 {160, 120, 0x00000000},
718 {320, 120, 0x005a5a5a},
719 {480, 120, 0x00000000},
720 {160, 240, 0x005a5a5a},
721 {320, 240, 0x00ffffff},
722 {480, 240, 0x005a5a5a},
723 {160, 360, 0x00000000},
724 {320, 360, 0x005a5a5a},
725 {480, 360, 0x00000000},
727 static const struct
729 const D3DLIGHT9 *light;
730 BOOL local_viewer;
731 const struct expected_color *expected;
732 unsigned int expected_count;
734 tests[] =
736 {&directional, FALSE, expected_directional,
737 sizeof(expected_directional) / sizeof(expected_directional[0])},
738 {&directional, TRUE, expected_directional_local,
739 sizeof(expected_directional_local) / sizeof(expected_directional_local[0])},
740 {&point, FALSE, expected_point,
741 sizeof(expected_point) / sizeof(expected_point[0])},
742 {&point, TRUE, expected_point_local,
743 sizeof(expected_point_local) / sizeof(expected_point_local[0])},
744 {&spot, FALSE, expected_spot,
745 sizeof(expected_spot) / sizeof(expected_spot[0])},
746 {&spot, TRUE, expected_spot_local,
747 sizeof(expected_spot_local) / sizeof(expected_spot_local[0])},
748 {&point_range, FALSE, expected_point_range,
749 sizeof(expected_point_range) / sizeof(expected_point_range[0])},
751 IDirect3DDevice9 *device;
752 D3DMATERIAL9 material;
753 IDirect3D9 *d3d;
754 D3DCOLOR color;
755 ULONG refcount;
756 HWND window;
757 HRESULT hr;
758 unsigned int i, j, x, y;
759 struct
761 struct vec3 position;
762 struct vec3 normal;
763 } *quad;
764 WORD *indices;
766 quad = HeapAlloc(GetProcessHeap(), 0, vertices_side * vertices_side * sizeof(*quad));
767 indices = HeapAlloc(GetProcessHeap(), 0, indices_count * sizeof(*indices));
768 for (i = 0, y = 0; y < vertices_side; ++y)
770 for (x = 0; x < vertices_side; ++x)
772 quad[i].position.x = x * 2.0f / (vertices_side - 1) - 1.0f;
773 quad[i].position.y = y * 2.0f / (vertices_side - 1) - 1.0f;
774 quad[i].position.z = 1.0f;
775 quad[i].normal.x = 0.0f;
776 quad[i].normal.y = 0.0f;
777 quad[i++].normal.z = -1.0f;
780 for (i = 0, y = 0; y < (vertices_side - 1); ++y)
782 for (x = 0; x < (vertices_side - 1); ++x)
784 indices[i++] = y * vertices_side + x + 1;
785 indices[i++] = y * vertices_side + x;
786 indices[i++] = (y + 1) * vertices_side + x;
787 indices[i++] = y * vertices_side + x + 1;
788 indices[i++] = (y + 1) * vertices_side + x;
789 indices[i++] = (y + 1) * vertices_side + x + 1;
793 window = create_window();
794 d3d = Direct3DCreate9(D3D_SDK_VERSION);
795 ok(!!d3d, "Failed to create a D3D object.\n");
796 if (!(device = create_device(d3d, window, window, TRUE)))
798 skip("Failed to create a D3D device, skipping tests.\n");
799 goto done;
802 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
803 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
804 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
805 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
806 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
807 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
808 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
809 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
810 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
811 ok(SUCCEEDED(hr), "Failed to disable z test, hr %#x.\n", hr);
812 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
813 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
815 hr = IDirect3DDevice9_SetFVF(device, fvf);
816 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
818 memset(&material, 0, sizeof(material));
819 material.Specular.r = 1.0f;
820 material.Specular.g = 1.0f;
821 material.Specular.b = 1.0f;
822 material.Specular.a = 1.0f;
823 material.Power = 30.0f;
824 hr = IDirect3DDevice9_SetMaterial(device, &material);
825 ok(SUCCEEDED(hr), "Failed to set material, hr %#x.\n", hr);
827 hr = IDirect3DDevice9_LightEnable(device, 0, TRUE);
828 ok(SUCCEEDED(hr), "Failed to enable light 0, hr %#x.\n", hr);
829 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
830 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#x.\n", hr);
832 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
834 hr = IDirect3DDevice9_SetLight(device, 0, tests[i].light);
835 ok(SUCCEEDED(hr), "Failed to set light parameters, hr %#x.\n", hr);
837 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LOCALVIEWER, tests[i].local_viewer);
838 ok(SUCCEEDED(hr), "Failed to set local viewer state, hr %#x.\n", hr);
840 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
841 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
843 hr = IDirect3DDevice9_BeginScene(device);
844 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
846 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST,
847 0, vertices_side * vertices_side, indices_count / 3, indices,
848 D3DFMT_INDEX16, quad, sizeof(quad[0]));
849 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
851 hr = IDirect3DDevice9_EndScene(device);
852 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
854 for (j = 0; j < tests[i].expected_count; ++j)
856 color = getPixelColor(device, tests[i].expected[j].x, tests[i].expected[j].y);
857 ok(color_match(color, tests[i].expected[j].color, 1),
858 "Expected color 0x%08x at location (%u, %u), got 0x%08x, case %u.\n",
859 tests[i].expected[j].color, tests[i].expected[j].x,
860 tests[i].expected[j].y, color, i);
864 refcount = IDirect3DDevice9_Release(device);
865 ok(!refcount, "Device has %u references left.\n", refcount);
866 done:
867 IDirect3D9_Release(d3d);
868 DestroyWindow(window);
869 HeapFree(GetProcessHeap(), 0, indices);
870 HeapFree(GetProcessHeap(), 0, quad);
873 static void clear_test(void)
875 static const D3DMATRIX mat =
877 1.0f, 0.0f, 0.0f, 0.0f,
878 0.0f, 1.0f, 0.0f, 0.0f,
879 0.0f, 0.0f, 1.0f, 0.0f,
880 0.0f, 0.0f, 0.0f, 1.0f,
881 }}};
882 static const struct
884 struct vec3 position;
885 DWORD diffuse;
887 quad[] =
889 {{-1.0f, -1.0f, 0.1f}, 0xff7f7f7f},
890 {{ 1.0f, -1.0f, 0.1f}, 0xff7f7f7f},
891 {{-1.0f, 1.0f, 0.1f}, 0xff7f7f7f},
892 {{ 1.0f, 1.0f, 0.1f}, 0xff7f7f7f},
894 IDirect3DSurface9 *surface0, *surface1, *backbuffer;
895 IDirect3DTexture9 *texture;
896 HRESULT hr;
897 D3DRECT rect[2];
898 D3DRECT rect_negneg;
899 DWORD color;
900 D3DVIEWPORT9 old_vp, vp;
901 RECT scissor;
902 DWORD oldColorWrite;
903 BOOL invalid_clear_failed = FALSE, srgb_supported;
904 IDirect3DDevice9 *device;
905 IDirect3D9 *d3d;
906 ULONG refcount;
907 HWND window;
909 window = create_window();
910 d3d = Direct3DCreate9(D3D_SDK_VERSION);
911 ok(!!d3d, "Failed to create a D3D object.\n");
912 if (!(device = create_device(d3d, window, window, TRUE)))
914 skip("Failed to create a D3D device, skipping tests.\n");
915 goto done;
918 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
919 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
921 /* Positive x, negative y */
922 rect[0].x1 = 0;
923 rect[0].y1 = 480;
924 rect[0].x2 = 320;
925 rect[0].y2 = 240;
927 /* Positive x, positive y */
928 rect[1].x1 = 0;
929 rect[1].y1 = 0;
930 rect[1].x2 = 320;
931 rect[1].y2 = 240;
932 /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
933 * returns D3D_OK, but ignores the rectangle silently
935 hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
936 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
937 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
939 /* negative x, negative y */
940 rect_negneg.x1 = 640;
941 rect_negneg.y1 = 240;
942 rect_negneg.x2 = 320;
943 rect_negneg.y2 = 0;
944 hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
945 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
946 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
948 color = getPixelColor(device, 160, 360); /* lower left quad */
949 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
950 color = getPixelColor(device, 160, 120); /* upper left quad */
951 if(invalid_clear_failed) {
952 /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
953 ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
954 } else {
955 /* If the negative rectangle was dropped silently, the correct ones are cleared */
956 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
958 color = getPixelColor(device, 480, 360); /* lower right quad */
959 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
960 color = getPixelColor(device, 480, 120); /* upper right quad */
961 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
963 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
965 /* Hack to work around a nvidia windows driver bug. The clear below is supposed to
966 * clear the red quad in the top left part of the render target. For some reason it
967 * doesn't work if the clear color is 0xffffffff on some versions of the Nvidia Windows
968 * driver(tested on 8.17.12.5896, Win7). A clear with a different color works around
969 * this bug and fixes the clear with the white color. Even 0xfeffffff works, but let's
970 * pick some obvious value
972 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbabe, 0.0, 0);
973 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
975 /* Test how the viewport affects clears */
976 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
977 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
978 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
979 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
981 vp.X = 160;
982 vp.Y = 120;
983 vp.Width = 160;
984 vp.Height = 120;
985 vp.MinZ = 0.0;
986 vp.MaxZ = 1.0;
987 hr = IDirect3DDevice9_SetViewport(device, &vp);
988 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
989 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
990 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
992 vp.X = 320;
993 vp.Y = 240;
994 vp.Width = 320;
995 vp.Height = 240;
996 vp.MinZ = 0.0;
997 vp.MaxZ = 1.0;
998 hr = IDirect3DDevice9_SetViewport(device, &vp);
999 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
1000 rect[0].x1 = 160;
1001 rect[0].y1 = 120;
1002 rect[0].x2 = 480;
1003 rect[0].y2 = 360;
1004 hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1005 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1007 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
1008 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
1010 color = getPixelColor(device, 158, 118);
1011 ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
1012 color = getPixelColor(device, 162, 118);
1013 ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
1014 color = getPixelColor(device, 158, 122);
1015 ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
1016 color = getPixelColor(device, 162, 122);
1017 ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
1019 color = getPixelColor(device, 318, 238);
1020 ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
1021 color = getPixelColor(device, 322, 238);
1022 ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
1023 color = getPixelColor(device, 318, 242);
1024 ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
1025 color = getPixelColor(device, 322, 242);
1026 ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
1028 color = getPixelColor(device, 478, 358);
1029 ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
1030 color = getPixelColor(device, 482, 358);
1031 ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
1032 color = getPixelColor(device, 478, 362);
1033 ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
1034 color = getPixelColor(device, 482, 362);
1035 ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
1037 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1039 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1040 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1042 SetRect(&scissor, 160, 120, 480, 360);
1043 hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
1044 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
1045 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
1046 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
1048 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1049 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1050 hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1051 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1053 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
1054 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
1056 color = getPixelColor(device, 158, 118);
1057 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
1058 color = getPixelColor(device, 162, 118);
1059 ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
1060 color = getPixelColor(device, 158, 122);
1061 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
1062 color = getPixelColor(device, 162, 122);
1063 ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
1065 color = getPixelColor(device, 158, 358);
1066 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
1067 color = getPixelColor(device, 162, 358);
1068 ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
1069 color = getPixelColor(device, 158, 358);
1070 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
1071 color = getPixelColor(device, 162, 362);
1072 ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
1074 color = getPixelColor(device, 478, 118);
1075 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
1076 color = getPixelColor(device, 478, 122);
1077 ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
1078 color = getPixelColor(device, 482, 122);
1079 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
1080 color = getPixelColor(device, 482, 358);
1081 ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
1083 color = getPixelColor(device, 478, 358);
1084 ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
1085 color = getPixelColor(device, 478, 362);
1086 ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
1087 color = getPixelColor(device, 482, 358);
1088 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
1089 color = getPixelColor(device, 482, 362);
1090 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
1092 color = getPixelColor(device, 318, 238);
1093 ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
1094 color = getPixelColor(device, 318, 242);
1095 ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
1096 color = getPixelColor(device, 322, 238);
1097 ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
1098 color = getPixelColor(device, 322, 242);
1099 ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
1101 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1103 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
1104 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1105 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
1106 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
1108 /* Same nvidia windows driver trouble with white clears as earlier in the same test */
1109 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbeef, 0.0, 0);
1110 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1112 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1113 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1115 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
1116 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
1118 /* Colorwriteenable does not affect the clear */
1119 color = getPixelColor(device, 320, 240);
1120 ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
1122 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1124 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
1125 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1127 rect[0].x1 = 0;
1128 rect[0].y1 = 0;
1129 rect[0].x2 = 640;
1130 rect[0].y2 = 480;
1131 hr = IDirect3DDevice9_Clear(device, 0, rect, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
1132 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1134 color = getPixelColor(device, 320, 240);
1135 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), 1),
1136 "Clear with count = 0, rect != NULL has color %08x\n", color);
1138 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1140 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1141 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1142 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1143 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1145 color = getPixelColor(device, 320, 240);
1146 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1147 "Clear with count = 1, rect = NULL has color %08x\n", color);
1149 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1151 /* Test D3DRS_SRGBWRITEENABLE interactions with clears. */
1152 srgb_supported = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
1153 D3DUSAGE_QUERY_SRGBWRITE, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8));
1154 trace("sRGB writing to D3DFMT_A8R8G8B8 is %ssupported.\n", srgb_supported ? "" : "not ");
1155 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1156 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
1158 color = getPixelColor(device, 320, 240);
1159 ok(color_match(color, 0x007f7f7f, 1), "Clear has color %08x.\n", color);
1161 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
1162 ok(SUCCEEDED(hr), "Failed to enable sRGB write, hr %#x.\n", hr);
1164 /* Draw something to make sure the SRGBWRITEENABLE setting is applied. */
1165 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
1166 ok(SUCCEEDED(hr), "Failed to set world matrix, hr %#x.\n", hr);
1167 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
1168 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
1169 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
1170 ok(SUCCEEDED(hr), "Failed to disable z test, hr %#x.\n", hr);
1171 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1172 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
1173 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
1174 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#x.\n", hr);
1175 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
1176 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
1177 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1178 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
1179 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1180 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1181 hr = IDirect3DDevice9_BeginScene(device);
1182 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1183 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad));
1184 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1185 hr = IDirect3DDevice9_EndScene(device);
1186 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1188 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1189 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
1191 color = getPixelColor(device, 320, 240);
1192 ok(color_match(color, 0x00bbbbbb, 1), "Clear has color %08x.\n", color);
1194 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
1195 ok(SUCCEEDED(hr), "Failed to disable sRGB write, hr %#x.\n", hr);
1197 /* Switching to a new render target seems to be enough to make Windows pick
1198 * up on the changed render state. */
1199 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 2, D3DUSAGE_RENDERTARGET,
1200 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
1201 ok(SUCCEEDED(hr), "Failed to create the offscreen render target, hr %#x.\n", hr);
1202 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1203 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
1204 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface0);
1205 ok(SUCCEEDED(hr), "Failed to get offscreen surface, hr %#x.\n", hr);
1206 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface0);
1207 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1209 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1210 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
1212 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1213 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1215 hr = IDirect3DDevice9_StretchRect(device, surface0, NULL, backbuffer, NULL, D3DTEXF_NONE);
1216 ok(SUCCEEDED(hr), "Failed to blit surface, hr %#x.\n", hr);
1218 color = getPixelColor(device, 64, 64);
1219 ok(color_match(color, 0x007f7f7f, 1), "Clear has color %08x.\n", color);
1221 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
1222 ok(SUCCEEDED(hr), "Failed to enable sRGB write, hr %#x.\n", hr);
1224 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface0);
1225 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1227 hr = IDirect3DDevice9_BeginScene(device);
1228 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1229 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad));
1230 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1231 hr = IDirect3DDevice9_EndScene(device);
1232 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1234 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1235 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
1237 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1238 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1240 hr = IDirect3DDevice9_StretchRect(device, surface0, NULL, backbuffer, NULL, D3DTEXF_NONE);
1241 ok(SUCCEEDED(hr), "Failed to blit surface, hr %#x.\n", hr);
1243 color = getPixelColor(device, 320, 240);
1244 ok(color_match(color, 0x00bbbbbb, 1), "Clear has color %08x.\n", color);
1246 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
1247 ok(SUCCEEDED(hr), "Failed to disable sRGB write, hr %#x.\n", hr);
1248 /* Switching to another surface of the same texture is also enough to make
1249 * the setting "stick". */
1250 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface1);
1251 ok(SUCCEEDED(hr), "Failed to get offscreen surface, hr %#x.\n", hr);
1252 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface1);
1253 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1255 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1256 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
1258 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1259 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1261 hr = IDirect3DDevice9_StretchRect(device, surface1, NULL, backbuffer, NULL, D3DTEXF_NONE);
1262 ok(SUCCEEDED(hr), "Failed to blit surface, hr %#x.\n", hr);
1264 color = getPixelColor(device, 320, 240);
1265 ok(color_match(color, 0x007f7f7f, 1), "Clear has color %08x.\n", color);
1267 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1269 IDirect3DSurface9_Release(surface1);
1270 IDirect3DSurface9_Release(surface0);
1271 IDirect3DSurface9_Release(backbuffer);
1272 IDirect3DTexture9_Release(texture);
1273 refcount = IDirect3DDevice9_Release(device);
1274 ok(!refcount, "Device has %u references left.\n", refcount);
1275 done:
1276 IDirect3D9_Release(d3d);
1277 DestroyWindow(window);
1280 static void color_fill_test(void)
1282 IDirect3DSurface9 *surface;
1283 IDirect3DTexture9 *texture;
1284 D3DCOLOR fill_color, color;
1285 DWORD fill_a, expected_a;
1286 IDirect3DDevice9 *device;
1287 IDirect3D9 *d3d;
1288 ULONG refcount;
1289 HWND window;
1290 HRESULT hr;
1291 static const struct
1293 D3DPOOL pool;
1294 DWORD usage;
1295 HRESULT hr;
1297 resource_types[] =
1299 {D3DPOOL_DEFAULT, 0, D3DERR_INVALIDCALL},
1300 {D3DPOOL_DEFAULT, D3DUSAGE_DYNAMIC, D3DERR_INVALIDCALL},
1301 {D3DPOOL_DEFAULT, D3DUSAGE_RENDERTARGET, D3D_OK},
1302 {D3DPOOL_SYSTEMMEM, 0, D3DERR_INVALIDCALL},
1303 {D3DPOOL_MANAGED, 0, D3DERR_INVALIDCALL},
1304 {D3DPOOL_SCRATCH, 0, D3DERR_INVALIDCALL},
1306 static const struct
1308 D3DFORMAT format;
1309 const char *name;
1310 enum
1312 CHECK_FILL_VALUE = 0x1,
1313 TODO_FILL_RETURN = 0x2,
1314 BLOCKS = 0x4,
1315 } flags;
1316 DWORD fill_value;
1318 formats[] =
1320 {D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8", CHECK_FILL_VALUE, 0xdeadbeef},
1321 /* D3DFMT_X8R8G8B8 either set X = A or X = 0, depending on the driver. */
1322 {D3DFMT_R5G6B5, "D3DFMT_R5G6B5", CHECK_FILL_VALUE, 0xadfdadfd},
1323 {D3DFMT_G16R16, "D3DFMT_G16R16", CHECK_FILL_VALUE, 0xbebeadad},
1324 /* Real hardware reliably fills the surface with the blue channel but
1325 * the testbot fills it with 0x00. Wine incorrectly uses the alpha
1326 * channel. Don't bother checking the result because P8 surfaces are
1327 * essentially useless in d3d9. */
1328 {D3DFMT_P8, "D3DFMT_P8", 0, 0xefefefef},
1329 /* Windows drivers produce different results for these formats.
1330 * No driver produces a YUV value that matches the input RGB
1331 * value, and no driver produces a proper DXT compression block.
1333 * Even the clear value 0 does not reliably produce a fill value
1334 * that will return vec4(0.0, 0.0, 0.0, 0.0) when sampled.
1336 * The YUV tests are disabled because they produce a driver-dependent
1337 * result on Wine.
1338 * {D3DFMT_YUY2, "D3DFMT_YUY2", BLOCKS, 0},
1339 * {D3DFMT_UYVY, "D3DFMT_UYVY", BLOCKS, 0}, */
1340 {D3DFMT_DXT1, "D3DFMT_DXT1", BLOCKS | TODO_FILL_RETURN, 0},
1341 /* Vendor-specific formats like ATI2N are a non-issue here since they're not
1342 * supported as offscreen plain surfaces and do not support D3DUSAGE_RENDERTARGET
1343 * when created as texture. */
1345 unsigned int i;
1346 D3DLOCKED_RECT locked_rect;
1347 DWORD *surface_data;
1348 static const RECT rect = {4, 4, 8, 8}, rect2 = {5, 5, 7, 7};
1350 window = create_window();
1351 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1352 ok(!!d3d, "Failed to create a D3D object.\n");
1353 if (!(device = create_device(d3d, window, window, TRUE)))
1355 skip("Failed to create a D3D device, skipping tests.\n");
1356 goto done;
1359 /* Test ColorFill on a the backbuffer (should pass) */
1360 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &surface);
1361 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1363 fill_color = 0x112233;
1364 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1365 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
1367 color = getPixelColor(device, 0, 0);
1368 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
1370 IDirect3DSurface9_Release(surface);
1372 /* Test ColorFill on a render target surface (should pass) */
1373 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8,
1374 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL );
1375 ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
1377 fill_color = 0x445566;
1378 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1379 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
1381 color = getPixelColorFromSurface(surface, 0, 0);
1382 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
1384 IDirect3DSurface9_Release(surface);
1386 /* Test ColorFill on an offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
1387 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1388 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surface, NULL);
1389 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
1391 fill_color = 0x778899;
1392 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1393 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
1395 color = getPixelColorFromSurface(surface, 0, 0);
1396 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
1398 IDirect3DSurface9_Release(surface);
1400 /* Try ColorFill on an offscreen surface in sysmem (should fail) */
1401 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1402 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1403 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
1405 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, 0);
1406 ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
1408 IDirect3DSurface9_Release(surface);
1410 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D16,
1411 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
1412 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr = %08x.\n", hr);
1414 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, 0);
1415 ok(hr == D3DERR_INVALIDCALL, "ColorFill on a depth stencil surface returned hr = %08x.\n", hr);
1417 IDirect3DSurface9_Release(surface);
1419 for (i = 0; i < sizeof(resource_types) / sizeof(resource_types[0]); i++)
1421 texture = NULL;
1422 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, resource_types[i].usage,
1423 D3DFMT_A8R8G8B8, resource_types[i].pool, &texture, NULL);
1424 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, i=%u.\n", hr, i);
1425 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1426 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x, i=%u.\n", hr, i);
1428 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1429 ok(hr == resource_types[i].hr, "Got unexpected hr %#x, expected %#x, i=%u.\n",
1430 hr, resource_types[i].hr, i);
1432 IDirect3DSurface9_Release(surface);
1433 IDirect3DTexture9_Release(texture);
1436 for (i = 0; i < sizeof(formats) / sizeof(formats[0]); i++)
1438 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
1439 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, formats[i].format) != D3D_OK)
1441 skip("Offscreenplain %s surfaces not supported, skipping colorfill test\n", formats[i].name);
1442 continue;
1445 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1446 formats[i].format, D3DPOOL_DEFAULT, &surface, NULL);
1447 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x, fmt=%s.\n", hr, formats[i].name);
1449 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, 0xdeadbeef);
1450 todo_wine_if (formats[i].flags & TODO_FILL_RETURN)
1451 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x, fmt=%s.\n", hr, formats[i].name);
1453 hr = IDirect3DDevice9_ColorFill(device, surface, &rect, 0xdeadbeef);
1454 todo_wine_if (formats[i].flags & TODO_FILL_RETURN)
1455 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x, fmt=%s.\n", hr, formats[i].name);
1457 if (SUCCEEDED(hr))
1459 hr = IDirect3DDevice9_ColorFill(device, surface, &rect2, 0xdeadbeef);
1460 if (formats[i].flags & BLOCKS)
1461 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, fmt=%s.\n", hr, formats[i].name);
1462 else
1463 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x, fmt=%s.\n", hr, formats[i].name);
1466 if (formats[i].flags & CHECK_FILL_VALUE)
1468 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, D3DLOCK_READONLY);
1469 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x, fmt=%s.\n", hr, formats[i].name);
1470 surface_data = locked_rect.pBits;
1471 fill_a = (surface_data[0] & 0xff000000) >> 24;
1472 expected_a = (formats[i].fill_value & 0xff000000) >> 24;
1473 /* Windows drivers disagree on how to promote the 8 bit per channel
1474 * input argument to 16 bit for D3DFMT_G16R16. */
1475 ok(color_match(surface_data[0], formats[i].fill_value, 2) &&
1476 abs((expected_a) - (fill_a)) < 3,
1477 "Expected clear value 0x%08x, got 0x%08x, fmt=%s.\n",
1478 formats[i].fill_value, surface_data[0], formats[i].name);
1479 hr = IDirect3DSurface9_UnlockRect(surface);
1480 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, fmt=%s.\n", hr, formats[i].name);
1483 IDirect3DSurface9_Release(surface);
1486 refcount = IDirect3DDevice9_Release(device);
1487 ok(!refcount, "Device has %u references left.\n", refcount);
1488 done:
1489 IDirect3D9_Release(d3d);
1490 DestroyWindow(window);
1494 * c7 mova ARGB mov ARGB
1495 * -2.4 -2 0x00ffff00 -3 0x00ff0000
1496 * -1.6 -2 0x00ffff00 -2 0x00ffff00
1497 * -0.4 0 0x0000ffff -1 0x0000ff00
1498 * 0.4 0 0x0000ffff 0 0x0000ffff
1499 * 1.6 2 0x00ff00ff 1 0x000000ff
1500 * 2.4 2 0x00ff00ff 2 0x00ff00ff
1502 static void test_mova(void)
1504 IDirect3DVertexDeclaration9 *vertex_declaration;
1505 IDirect3DVertexShader9 *mova_shader;
1506 IDirect3DVertexShader9 *mov_shader;
1507 IDirect3DDevice9 *device;
1508 unsigned int i, j;
1509 IDirect3D9 *d3d;
1510 ULONG refcount;
1511 D3DCAPS9 caps;
1512 HWND window;
1513 HRESULT hr;
1515 static const DWORD mova_test[] =
1517 0xfffe0200, /* vs_2_0 */
1518 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1519 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
1520 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
1521 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
1522 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
1523 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
1524 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
1525 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
1526 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
1527 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
1528 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1529 0x0000ffff /* END */
1531 static const DWORD mov_test[] =
1533 0xfffe0101, /* vs_1_1 */
1534 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1535 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
1536 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
1537 0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
1538 0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
1539 0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
1540 0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
1541 0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
1542 0x00000001, 0xb0010000, 0xa0000007, /* mov a0.x, c7.x */
1543 0x00000001, 0xd00f0000, 0xa0e42003, /* mov oD0, c[a0.x + 3] */
1544 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1545 0x0000ffff /* END */
1547 static const struct
1549 float in[4];
1550 DWORD out;
1552 test_data[2][6] =
1555 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
1556 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
1557 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
1558 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
1559 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
1560 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
1563 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
1564 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
1565 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
1566 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
1567 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
1568 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
1571 static const struct vec3 quad[] =
1573 {-1.0f, -1.0f, 0.0f},
1574 {-1.0f, 1.0f, 0.0f},
1575 { 1.0f, -1.0f, 0.0f},
1576 { 1.0f, 1.0f, 0.0f},
1578 static const D3DVERTEXELEMENT9 decl_elements[] =
1580 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1581 D3DDECL_END()
1584 window = create_window();
1585 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1586 ok(!!d3d, "Failed to create a D3D object.\n");
1587 if (!(device = create_device(d3d, window, window, TRUE)))
1589 skip("Failed to create a D3D device, skipping tests.\n");
1590 goto done;
1593 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1594 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1595 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
1597 skip("No vs_2_0 support, skipping tests.\n");
1598 IDirect3DDevice9_Release(device);
1599 goto done;
1602 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
1603 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1604 hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
1605 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1606 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1607 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1608 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1609 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1611 hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
1612 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1613 for (j = 0; j < sizeof(test_data) / sizeof(*test_data); ++j)
1615 for (i = 0; i < sizeof(*test_data) / sizeof(**test_data); ++i)
1617 DWORD color;
1619 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
1620 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
1622 hr = IDirect3DDevice9_BeginScene(device);
1623 ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
1625 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
1626 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1628 hr = IDirect3DDevice9_EndScene(device);
1629 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
1631 color = getPixelColor(device, 320, 240);
1632 ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
1633 test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
1635 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1636 ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
1638 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1639 ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
1641 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
1642 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1645 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1646 IDirect3DVertexShader9_Release(mova_shader);
1647 IDirect3DVertexShader9_Release(mov_shader);
1648 refcount = IDirect3DDevice9_Release(device);
1649 ok(!refcount, "Device has %u references left.\n", refcount);
1650 done:
1651 IDirect3D9_Release(d3d);
1652 DestroyWindow(window);
1655 static void fog_test(void)
1657 float start = 0.0f, end = 1.0f;
1658 IDirect3DDevice9 *device;
1659 IDirect3D9 *d3d;
1660 D3DCOLOR color;
1661 ULONG refcount;
1662 D3DCAPS9 caps;
1663 HWND window;
1664 HRESULT hr;
1665 int i;
1667 /* Gets full z based fog with linear fog, no fog with specular color. */
1668 static const struct
1670 float x, y, z;
1671 D3DCOLOR diffuse;
1672 D3DCOLOR specular;
1674 untransformed_1[] =
1676 {-1.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
1677 {-1.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
1678 { 0.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
1679 { 0.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
1681 /* Ok, I am too lazy to deal with transform matrices. */
1682 untransformed_2[] =
1684 {-1.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
1685 {-1.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
1686 { 0.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
1687 { 0.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
1689 untransformed_3[] =
1691 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1692 {-1.0f, 1.0f, 0.5f, 0xffff0000, 0xff000000},
1693 { 1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1694 { 1.0f, 1.0f, 0.5f, 0xffff0000, 0xff000000},
1696 far_quad1[] =
1698 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1699 {-1.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
1700 { 0.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
1701 { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1703 far_quad2[] =
1705 {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1706 {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
1707 { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
1708 { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1710 /* Untransformed ones. Give them a different diffuse color to make the
1711 * test look nicer. It also makes making sure that they are drawn
1712 * correctly easier. */
1713 static const struct
1715 float x, y, z, rhw;
1716 D3DCOLOR diffuse;
1717 D3DCOLOR specular;
1719 transformed_1[] =
1721 {320.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1722 {640.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1723 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1724 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1726 transformed_2[] =
1728 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1729 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1730 {640.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1731 {320.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1733 static const struct
1735 struct vec3 position;
1736 DWORD diffuse;
1738 rev_fog_quads[] =
1740 {{-1.0f, -1.0f, 0.1f}, 0x000000ff},
1741 {{-1.0f, 0.0f, 0.1f}, 0x000000ff},
1742 {{ 0.0f, 0.0f, 0.1f}, 0x000000ff},
1743 {{ 0.0f, -1.0f, 0.1f}, 0x000000ff},
1745 {{ 0.0f, -1.0f, 0.9f}, 0x000000ff},
1746 {{ 0.0f, 0.0f, 0.9f}, 0x000000ff},
1747 {{ 1.0f, 0.0f, 0.9f}, 0x000000ff},
1748 {{ 1.0f, -1.0f, 0.9f}, 0x000000ff},
1750 {{ 0.0f, 0.0f, 0.4f}, 0x000000ff},
1751 {{ 0.0f, 1.0f, 0.4f}, 0x000000ff},
1752 {{ 1.0f, 1.0f, 0.4f}, 0x000000ff},
1753 {{ 1.0f, 0.0f, 0.4f}, 0x000000ff},
1755 {{-1.0f, 0.0f, 0.7f}, 0x000000ff},
1756 {{-1.0f, 1.0f, 0.7f}, 0x000000ff},
1757 {{ 0.0f, 1.0f, 0.7f}, 0x000000ff},
1758 {{ 0.0f, 0.0f, 0.7f}, 0x000000ff},
1760 static const D3DMATRIX ident_mat =
1762 1.0f, 0.0f, 0.0f, 0.0f,
1763 0.0f, 1.0f, 0.0f, 0.0f,
1764 0.0f, 0.0f, 1.0f, 0.0f,
1765 0.0f, 0.0f, 0.0f, 1.0f
1766 }}};
1767 static const D3DMATRIX world_mat1 =
1769 1.0f, 0.0f, 0.0f, 0.0f,
1770 0.0f, 1.0f, 0.0f, 0.0f,
1771 0.0f, 0.0f, 1.0f, 0.0f,
1772 0.0f, 0.0f, -0.5f, 1.0f
1773 }}};
1774 static const D3DMATRIX world_mat2 =
1776 1.0f, 0.0f, 0.0f, 0.0f,
1777 0.0f, 1.0f, 0.0f, 0.0f,
1778 0.0f, 0.0f, 1.0f, 0.0f,
1779 0.0f, 0.0f, 1.0f, 1.0f
1780 }}};
1781 static const D3DMATRIX proj_mat =
1783 1.0f, 0.0f, 0.0f, 0.0f,
1784 0.0f, 1.0f, 0.0f, 0.0f,
1785 0.0f, 0.0f, 1.0f, 0.0f,
1786 0.0f, 0.0f, -1.0f, 1.0f
1787 }}};
1788 static const WORD Indices[] = {0, 1, 2, 2, 3, 0};
1789 static const WORD Indices2[] =
1791 0, 1, 2, 2, 3, 0,
1792 4, 5, 6, 6, 7, 4,
1793 8, 9, 10, 10, 11, 8,
1794 12, 13, 14, 14, 15, 12,
1797 window = create_window();
1798 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1799 ok(!!d3d, "Failed to create a D3D object.\n");
1800 if (!(device = create_device(d3d, window, window, TRUE)))
1802 skip("Failed to create a D3D device, skipping tests.\n");
1803 goto done;
1806 memset(&caps, 0, sizeof(caps));
1807 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1808 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
1809 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1810 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1812 /* Setup initial states: No lighting, fog on, fog color */
1813 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
1814 ok(SUCCEEDED(hr), "Failed to disable D3DRS_ZENABLE, hr %#x.\n", hr);
1815 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1816 ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
1817 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1818 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
1819 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xff00ff00 /* A nice green */);
1820 ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
1821 /* Some of the tests seem to depend on the projection matrix explicitly
1822 * being set to an identity matrix, even though that's the default.
1823 * (AMD Radeon HD 6310, Windows 7) */
1824 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
1825 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
1827 /* First test: Both table fog and vertex fog off */
1828 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1829 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
1830 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1831 ok(hr == D3D_OK, "Turning off vertex fog returned %08x\n", hr);
1833 /* Start = 0, end = 1. Should be default, but set them */
1834 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1835 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1836 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1837 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1839 hr = IDirect3DDevice9_BeginScene(device);
1840 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1842 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1843 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1845 /* Untransformed, vertex fog = NONE, table fog = NONE:
1846 * Read the fog weighting from the specular color. */
1847 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1848 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1849 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1851 /* That makes it use the Z value */
1852 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1853 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex mode, hr %#x.\n", hr);
1854 /* Untransformed, vertex fog != none (or table fog != none):
1855 * Use the Z value as input into the equation. */
1856 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1857 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1858 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1860 /* transformed verts */
1861 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1862 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1863 /* Transformed, vertex fog != NONE, pixel fog == NONE:
1864 * Use specular color alpha component. */
1865 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1866 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_1, sizeof(transformed_1[0]));
1867 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1869 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1870 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog table mode, hr %#x.\n", hr);
1871 /* Transformed, table fog != none, vertex anything:
1872 * Use Z value as input to the fog equation. */
1873 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1874 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_2, sizeof(transformed_2[0]));
1875 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1877 hr = IDirect3DDevice9_EndScene(device);
1878 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1880 color = getPixelColor(device, 160, 360);
1881 ok(color == 0x00ff0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1882 color = getPixelColor(device, 160, 120);
1883 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
1884 color = getPixelColor(device, 480, 120);
1885 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1886 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1888 color = getPixelColor(device, 480, 360);
1889 ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
1891 else
1893 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1894 * The settings above result in no fogging with vertex fog
1896 color = getPixelColor(device, 480, 120);
1897 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1898 trace("Info: Table fog not supported by this device\n");
1900 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1902 /* Now test the special case fogstart == fogend */
1903 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1904 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1906 hr = IDirect3DDevice9_BeginScene(device);
1907 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1909 start = 512;
1910 end = 512;
1911 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
1912 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#x.\n", hr);
1913 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
1914 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#x.\n", hr);
1916 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1917 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1918 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1919 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex mode, hr %#x.\n", hr);
1920 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1921 ok(SUCCEEDED(hr), "Failed to set D3DFOG_NONE fog table mode, hr %#x.\n", hr);
1923 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512.
1924 * Would result in a completely fog-free primitive because start > zcoord,
1925 * but because start == end, the primitive is fully covered by fog. The
1926 * same happens to the 2nd untransformed quad with z = 1.0. The third
1927 * transformed quad remains unfogged because the fogcoords are read from
1928 * the specular color and has fixed fogstart and fogend. */
1929 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1930 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1931 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1932 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1933 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1934 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1936 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1937 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1938 /* Transformed, vertex fog != NONE, pixel fog == NONE:
1939 * Use specular color alpha component. */
1940 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1941 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_1, sizeof(transformed_1[0]));
1942 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1944 hr = IDirect3DDevice9_EndScene(device);
1945 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1947 color = getPixelColor(device, 160, 360);
1948 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1949 color = getPixelColor(device, 160, 120);
1950 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1951 color = getPixelColor(device, 480, 120);
1952 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1953 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1955 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1956 * but without shaders it seems to work everywhere
1958 end = 0.2;
1959 start = 0.8;
1960 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1961 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1962 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1963 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1964 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1965 ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1967 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1968 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1969 * so skip this for now
1971 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1972 const char *mode = (i ? "table" : "vertex");
1973 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1974 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1975 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1976 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1977 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1978 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1979 hr = IDirect3DDevice9_BeginScene(device);
1980 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1981 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 16 /* NumVerts */,
1982 8 /* PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads, sizeof(rev_fog_quads[0]));
1983 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1984 hr = IDirect3DDevice9_EndScene(device);
1985 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1987 color = getPixelColor(device, 160, 360);
1988 ok(color_match(color, 0x0000ff00, 1),
1989 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1991 color = getPixelColor(device, 160, 120);
1992 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1993 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1995 color = getPixelColor(device, 480, 120);
1996 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1997 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1999 color = getPixelColor(device, 480, 360);
2000 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
2002 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2004 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
2005 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
2006 break;
2010 if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
2012 /* A simple fog + non-identity world matrix test */
2013 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat1);
2014 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %#08x\n", hr);
2016 start = 0.0;
2017 end = 1.0;
2018 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
2019 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
2020 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
2021 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
2022 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
2023 ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
2024 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
2025 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
2027 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2028 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %#08x\n", hr);
2030 hr = IDirect3DDevice9_BeginScene(device);
2031 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2033 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
2034 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
2036 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2037 2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
2038 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2039 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2040 2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
2041 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2043 hr = IDirect3DDevice9_EndScene(device);
2044 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2046 color = getPixelColor(device, 160, 360);
2047 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 4),
2048 "Unfogged quad has color %08x\n", color);
2049 color = getPixelColor(device, 160, 120);
2050 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2051 "Fogged out quad has color %08x\n", color);
2053 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2055 /* Test fog behavior with an orthogonal (but non-identity) projection matrix */
2056 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat2);
2057 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
2058 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &proj_mat);
2059 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
2061 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2062 ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
2064 hr = IDirect3DDevice9_BeginScene(device);
2065 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2067 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
2068 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
2070 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2071 2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
2072 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2073 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2074 2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
2075 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2077 hr = IDirect3DDevice9_EndScene(device);
2078 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2080 color = getPixelColor(device, 160, 360);
2081 ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
2082 color = getPixelColor(device, 160, 120);
2083 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2084 "Fogged out quad has color %08x\n", color);
2086 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2088 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &ident_mat);
2089 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
2090 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
2091 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
2093 else
2095 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
2098 /* Test RANGEFOG vs FOGTABLEMODE */
2099 if ((caps.RasterCaps & (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE)) ==
2100 (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE))
2102 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2103 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
2104 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
2105 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
2107 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, TRUE);
2108 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
2110 /* z=0.5, x = +/- 1.0, y = +/- 1.0. In case of z fog the fog coordinate is
2111 * 0.5. With range fog it is sqrt(x*x + y*y + z*z) = 1.5 for all vertices.
2112 * Note that the fog coordinate is interpolated linearly across the vertices,
2113 * so the different eye distance at the screen center should not matter. */
2114 start = 0.75f;
2115 end = 0.75001f;
2116 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
2117 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
2118 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
2119 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
2121 /* Table fog: Range fog is not used */
2122 hr = IDirect3DDevice9_BeginScene(device);
2123 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2125 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
2126 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog table mode, hr %#x.\n", hr);
2127 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
2128 untransformed_3, sizeof(*untransformed_3));
2129 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2131 hr = IDirect3DDevice9_EndScene(device);
2132 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2134 color = getPixelColor(device, 10, 10);
2135 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2136 color = getPixelColor(device, 630, 10);
2137 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2138 color = getPixelColor(device, 10, 470);
2139 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2140 color = getPixelColor(device, 630, 470);
2141 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2143 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2144 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
2146 /* Vertex fog: Rangefog is used */
2147 hr = IDirect3DDevice9_BeginScene(device);
2148 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2150 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
2151 ok(SUCCEEDED(hr), "Failed to set D3DFOG_NONE fog table mode, hr %#x.\n", hr);
2152 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
2153 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex mode, hr %#x.\n", hr);
2154 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
2155 untransformed_3, sizeof(*untransformed_3));
2156 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2158 hr = IDirect3DDevice9_EndScene(device);
2159 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2161 color = getPixelColor(device, 10, 10);
2162 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2163 "Rangefog with vertex fog returned color 0x%08x\n", color);
2164 color = getPixelColor(device, 630, 10);
2165 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2166 "Rangefog with vertex fog returned color 0x%08x\n", color);
2167 color = getPixelColor(device, 10, 470);
2168 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2169 "Rangefog with vertex fog returned color 0x%08x\n", color);
2170 color = getPixelColor(device, 630, 470);
2171 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2172 "Rangefog with vertex fog returned color 0x%08x\n", color);
2174 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2175 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
2177 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, FALSE);
2178 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
2180 else
2182 skip("Range fog or table fog not supported, skipping range fog tests\n");
2185 refcount = IDirect3DDevice9_Release(device);
2186 ok(!refcount, "Device has %u references left.\n", refcount);
2187 done:
2188 IDirect3D9_Release(d3d);
2189 DestroyWindow(window);
2192 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
2193 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
2194 * regardless of the actual addressing mode set. The way this test works is
2195 * that we sample in one of the corners of the cubemap with filtering enabled,
2196 * and check the interpolated color. There are essentially two reasonable
2197 * things an implementation can do: Either pick one of the faces and
2198 * interpolate the edge texel with itself (i.e., clamp within the face), or
2199 * interpolate between the edge texels of the three involved faces. It should
2200 * never involve the border color or the other side (texcoord wrapping) of a
2201 * face in the interpolation. */
2202 static void test_cube_wrap(void)
2204 IDirect3DVertexDeclaration9 *vertex_declaration;
2205 IDirect3DSurface9 *face_surface, *surface;
2206 IDirect3DCubeTexture9 *texture;
2207 D3DLOCKED_RECT locked_rect;
2208 IDirect3DDevice9 *device;
2209 unsigned int x, y, face;
2210 IDirect3D9 *d3d;
2211 ULONG refcount;
2212 D3DCAPS9 caps;
2213 HWND window;
2214 HRESULT hr;
2216 static const float quad[][6] =
2218 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2219 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2220 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2221 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2223 static const D3DVERTEXELEMENT9 decl_elements[] =
2225 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2226 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2227 D3DDECL_END()
2229 static const struct
2231 D3DTEXTUREADDRESS mode;
2232 const char *name;
2234 address_modes[] =
2236 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
2237 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
2238 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
2239 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
2240 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
2243 window = create_window();
2244 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2245 ok(!!d3d, "Failed to create a D3D object.\n");
2246 if (!(device = create_device(d3d, window, window, TRUE)))
2248 skip("Failed to create a D3D device, skipping tests.\n");
2249 goto done;
2252 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2253 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2254 if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP))
2256 skip("No cube texture support, skipping tests.\n");
2257 IDirect3DDevice9_Release(device);
2258 goto done;
2261 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
2262 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
2263 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2264 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
2266 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
2267 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
2268 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
2270 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
2271 D3DPOOL_DEFAULT, &texture, NULL);
2272 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
2274 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
2275 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2277 for (y = 0; y < 128; ++y)
2279 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2280 for (x = 0; x < 64; ++x)
2282 *ptr++ = 0xff0000ff;
2284 for (x = 64; x < 128; ++x)
2286 *ptr++ = 0xffff0000;
2290 hr = IDirect3DSurface9_UnlockRect(surface);
2291 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2293 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
2294 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
2296 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
2297 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
2299 IDirect3DSurface9_Release(face_surface);
2301 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
2302 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2304 for (y = 0; y < 128; ++y)
2306 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2307 for (x = 0; x < 64; ++x)
2309 *ptr++ = 0xffff0000;
2311 for (x = 64; x < 128; ++x)
2313 *ptr++ = 0xff0000ff;
2317 hr = IDirect3DSurface9_UnlockRect(surface);
2318 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2320 /* Create cube faces */
2321 for (face = 1; face < 6; ++face)
2323 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
2324 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
2326 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
2327 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
2329 IDirect3DSurface9_Release(face_surface);
2332 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
2333 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2335 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
2336 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2337 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
2338 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2339 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
2340 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
2342 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2343 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2345 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
2347 DWORD color;
2349 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
2350 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
2351 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
2352 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
2354 hr = IDirect3DDevice9_BeginScene(device);
2355 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2357 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2358 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2360 hr = IDirect3DDevice9_EndScene(device);
2361 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2363 color = getPixelColor(device, 320, 240);
2364 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
2365 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
2366 color, address_modes[x].name);
2368 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2369 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2371 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
2372 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
2375 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2376 IDirect3DCubeTexture9_Release(texture);
2377 IDirect3DSurface9_Release(surface);
2378 refcount = IDirect3DDevice9_Release(device);
2379 ok(!refcount, "Device has %u references left.\n", refcount);
2380 done:
2381 IDirect3D9_Release(d3d);
2382 DestroyWindow(window);
2385 static void offscreen_test(void)
2387 IDirect3DSurface9 *backbuffer, *offscreen;
2388 IDirect3DTexture9 *offscreenTexture;
2389 IDirect3DDevice9 *device;
2390 IDirect3D9 *d3d;
2391 D3DCOLOR color;
2392 ULONG refcount;
2393 HWND window;
2394 HRESULT hr;
2396 static const float quad[][5] =
2398 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
2399 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
2400 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
2401 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
2404 window = create_window();
2405 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2406 ok(!!d3d, "Failed to create a D3D object.\n");
2407 if (!(device = create_device(d3d, window, window, TRUE)))
2409 skip("Failed to create a D3D device, skipping tests.\n");
2410 goto done;
2413 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
2414 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
2416 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2417 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
2418 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
2419 if (!offscreenTexture)
2421 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5.\n");
2422 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2423 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
2424 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
2425 if (!offscreenTexture)
2427 skip("Cannot create an offscreen render target.\n");
2428 IDirect3DDevice9_Release(device);
2429 goto done;
2433 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2434 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2436 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
2437 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
2439 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2440 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
2442 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
2443 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
2444 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2445 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
2446 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2447 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2448 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2449 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2450 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2451 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2453 hr = IDirect3DDevice9_BeginScene(device);
2454 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2456 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
2457 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2458 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 1.0f, 0);
2459 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2461 /* Draw without textures - Should result in a white quad. */
2462 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2463 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2465 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
2466 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2467 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)offscreenTexture);
2468 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2470 /* This time with the texture. */
2471 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2472 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2474 hr = IDirect3DDevice9_EndScene(device);
2475 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2477 /* Center quad - should be white */
2478 color = getPixelColor(device, 320, 240);
2479 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2480 /* Some quad in the cleared part of the texture */
2481 color = getPixelColor(device, 170, 240);
2482 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
2483 /* Part of the originally cleared back buffer */
2484 color = getPixelColor(device, 10, 10);
2485 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2486 color = getPixelColor(device, 10, 470);
2487 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2489 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2491 IDirect3DSurface9_Release(backbuffer);
2492 IDirect3DTexture9_Release(offscreenTexture);
2493 IDirect3DSurface9_Release(offscreen);
2494 refcount = IDirect3DDevice9_Release(device);
2495 ok(!refcount, "Device has %u references left.\n", refcount);
2496 done:
2497 IDirect3D9_Release(d3d);
2498 DestroyWindow(window);
2501 /* This test tests fog in combination with shaders.
2502 * What's tested: linear fog (vertex and table) with pixel shader
2503 * linear table fog with non foggy vertex shader
2504 * vertex fog with foggy vertex shader, non-linear
2505 * fog with shader, non-linear fog with foggy shader,
2506 * linear table fog with foggy shader */
2507 static void fog_with_shader_test(void)
2509 IDirect3DVertexShader9 *vertex_shader[4] = {NULL, NULL, NULL, NULL};
2510 IDirect3DPixelShader9 *pixel_shader[3] = {NULL, NULL, NULL};
2511 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
2512 IDirect3DDevice9 *device;
2513 unsigned int i, j;
2514 IDirect3D9 *d3d;
2515 ULONG refcount;
2516 D3DCAPS9 caps;
2517 DWORD color;
2518 HWND window;
2519 HRESULT hr;
2520 union
2522 float f;
2523 DWORD i;
2524 } start, end;
2526 /* basic vertex shader without fog computation ("non foggy") */
2527 static const DWORD vertex_shader_code1[] =
2529 0xfffe0101, /* vs_1_1 */
2530 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2531 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
2532 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2533 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
2534 0x0000ffff
2536 /* basic vertex shader with reversed fog computation ("foggy") */
2537 static const DWORD vertex_shader_code2[] =
2539 0xfffe0101, /* vs_1_1 */
2540 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2541 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
2542 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
2543 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2544 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
2545 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
2546 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
2547 0x0000ffff
2549 /* basic vertex shader with reversed fog computation ("foggy"), vs_2_0 */
2550 static const DWORD vertex_shader_code3[] =
2552 0xfffe0200, /* vs_2_0 */
2553 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2554 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
2555 0x05000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
2556 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2557 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
2558 0x03000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
2559 0x03000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
2560 0x0000ffff
2562 /* basic pixel shader */
2563 static const DWORD pixel_shader_code[] =
2565 0xffff0101, /* ps_1_1 */
2566 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
2567 0x0000ffff
2569 static const DWORD pixel_shader_code2[] =
2571 0xffff0200, /* ps_2_0 */
2572 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
2573 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
2574 0x0000ffff
2576 struct
2578 struct vec3 position;
2579 DWORD diffuse;
2581 quad[] =
2583 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
2584 {{-1.0f, 1.0f, 0.0f}, 0xffff0000},
2585 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
2586 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000},
2588 static const D3DVERTEXELEMENT9 decl_elements[] =
2590 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2591 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
2592 D3DDECL_END()
2594 /* This reference data was collected on a nVidia GeForce 7600GS driver
2595 * version 84.19 DirectX version 9.0c on Windows XP. */
2596 static const struct test_data_t
2598 int vshader;
2599 int pshader;
2600 D3DFOGMODE vfog;
2601 D3DFOGMODE tfog;
2602 unsigned int color[11];
2604 test_data[] =
2606 /* only pixel shader: */
2607 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
2608 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2609 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2610 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
2611 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2612 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2613 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
2614 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2615 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2616 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2617 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2618 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2619 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
2620 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2621 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2623 /* vertex shader */
2624 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
2625 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2626 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2627 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
2628 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2629 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2630 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
2631 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2632 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2634 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
2635 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2636 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2637 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
2638 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2639 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2641 /* vertex shader and pixel shader */
2642 /* The next 4 tests would read the fog coord output, but it isn't available.
2643 * The result is a fully fogged quad, no matter what the Z coord is. This is on
2644 * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
2645 * These tests should be disabled if some other hardware behaves differently
2647 {1, 1, D3DFOG_NONE, D3DFOG_NONE,
2648 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2649 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2650 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2651 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2652 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2653 {1, 1, D3DFOG_EXP, D3DFOG_NONE,
2654 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2655 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2656 {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
2657 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2658 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2660 /* These use the Z coordinate with linear table fog */
2661 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
2662 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2663 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2664 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
2665 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2666 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2667 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
2668 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2669 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2670 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
2671 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2672 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2674 /* Non-linear table fog without fog coord */
2675 {1, 1, D3DFOG_NONE, D3DFOG_EXP,
2676 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
2677 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
2678 {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
2679 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
2680 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
2682 /* These tests fail on older Nvidia drivers */
2683 /* foggy vertex shader */
2684 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
2685 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2686 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2687 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
2688 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2689 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2690 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
2691 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2692 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2693 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
2694 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2695 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2697 {3, 0, D3DFOG_NONE, D3DFOG_NONE,
2698 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2699 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2700 {3, 0, D3DFOG_EXP, D3DFOG_NONE,
2701 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2702 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2703 {3, 0, D3DFOG_EXP2, D3DFOG_NONE,
2704 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2705 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2706 {3, 0, D3DFOG_LINEAR, D3DFOG_NONE,
2707 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2708 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2710 /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
2711 * all using the fixed fog-coord linear fog
2713 /* vs_1_1 with ps_1_1 */
2714 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
2715 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2716 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2717 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
2718 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2719 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2720 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
2721 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2722 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2723 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2724 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2725 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2727 /* vs_2_0 with ps_1_1 */
2728 {3, 1, D3DFOG_NONE, D3DFOG_NONE,
2729 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2730 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2731 {3, 1, D3DFOG_EXP, D3DFOG_NONE,
2732 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2733 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2734 {3, 1, D3DFOG_EXP2, D3DFOG_NONE,
2735 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2736 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2737 {3, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2738 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2739 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2741 /* vs_1_1 with ps_2_0 */
2742 {2, 2, D3DFOG_NONE, D3DFOG_NONE,
2743 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2744 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2745 {2, 2, D3DFOG_EXP, D3DFOG_NONE,
2746 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2747 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2748 {2, 2, D3DFOG_EXP2, D3DFOG_NONE,
2749 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2750 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2751 {2, 2, D3DFOG_LINEAR, D3DFOG_NONE,
2752 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2753 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2755 /* vs_2_0 with ps_2_0 */
2756 {3, 2, D3DFOG_NONE, D3DFOG_NONE,
2757 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2758 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2759 {3, 2, D3DFOG_EXP, D3DFOG_NONE,
2760 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2761 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2762 {3, 2, D3DFOG_EXP2, D3DFOG_NONE,
2763 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2764 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2765 {3, 2, D3DFOG_LINEAR, D3DFOG_NONE,
2766 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2767 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2769 /* These use table fog. Here the shader-provided fog coordinate is
2770 * ignored and the z coordinate used instead
2772 {2, 1, D3DFOG_NONE, D3DFOG_EXP,
2773 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
2774 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
2775 {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
2776 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
2777 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
2778 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
2779 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2780 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2782 static const D3DMATRIX identity =
2784 1.0f, 0.0f, 0.0f, 0.0f,
2785 0.0f, 1.0f, 0.0f, 0.0f,
2786 0.0f, 0.0f, 1.0f, 0.0f,
2787 0.0f, 0.0f, 0.0f, 1.0f,
2788 }}};
2790 window = create_window();
2791 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2792 ok(!!d3d, "Failed to create a D3D object.\n");
2793 if (!(device = create_device(d3d, window, window, TRUE)))
2795 skip("Failed to create a D3D device, skipping tests.\n");
2796 goto done;
2799 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2800 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2801 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0) || caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
2803 skip("No shader model 2 support, skipping tests.\n");
2804 IDirect3DDevice9_Release(device);
2805 goto done;
2808 /* NOTE: Changing these values will not affect the tests with foggy vertex
2809 * shader, as the values are hardcoded in the shader. */
2810 start.f = 0.1f;
2811 end.f = 0.9f;
2813 /* Some of the tests seem to depend on the projection matrix explicitly
2814 * being set to an identity matrix, even though that's the default.
2815 * (AMD Radeon HD 6310, Windows 7) */
2816 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
2817 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
2819 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
2820 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2821 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
2822 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2823 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code3, &vertex_shader[3]);
2824 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2825 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
2826 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2827 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code2, &pixel_shader[2]);
2828 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2829 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
2830 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
2832 /* Setup initial states: No lighting, fog on, fog color */
2833 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2834 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
2835 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
2836 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
2837 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xff00ff00 /* A nice green */);
2838 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
2839 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2840 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2842 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
2843 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
2844 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
2845 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
2847 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
2848 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
2849 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
2850 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
2851 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
2853 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
2855 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
2856 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2857 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
2858 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2859 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
2860 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2861 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
2862 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2864 for(j=0; j < 11; j++)
2866 /* Don't use the whole zrange to prevent rounding errors */
2867 quad[0].position.z = 0.001f + (float)j / 10.02f;
2868 quad[1].position.z = 0.001f + (float)j / 10.02f;
2869 quad[2].position.z = 0.001f + (float)j / 10.02f;
2870 quad[3].position.z = 0.001f + (float)j / 10.02f;
2872 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff00ff, 1.0f, 0);
2873 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2875 hr = IDirect3DDevice9_BeginScene(device);
2876 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
2878 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2879 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2881 hr = IDirect3DDevice9_EndScene(device);
2882 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
2884 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
2885 color = getPixelColor(device, 128, 240);
2886 ok(color_match(color, test_data[i].color[j], 13),
2887 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
2888 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
2891 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2893 IDirect3DVertexShader9_Release(vertex_shader[1]);
2894 IDirect3DVertexShader9_Release(vertex_shader[2]);
2895 IDirect3DVertexShader9_Release(vertex_shader[3]);
2896 IDirect3DPixelShader9_Release(pixel_shader[1]);
2897 IDirect3DPixelShader9_Release(pixel_shader[2]);
2898 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2899 refcount = IDirect3DDevice9_Release(device);
2900 ok(!refcount, "Device has %u references left.\n", refcount);
2901 done:
2902 IDirect3D9_Release(d3d);
2903 DestroyWindow(window);
2906 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
2907 unsigned int i, x, y;
2908 HRESULT hr;
2909 IDirect3DTexture9 *texture[2] = {NULL, NULL};
2910 D3DLOCKED_RECT locked_rect;
2912 /* Generate the textures */
2913 for(i=0; i<2; i++)
2915 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
2916 D3DPOOL_MANAGED, &texture[i], NULL);
2917 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
2919 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
2920 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2921 for (y = 0; y < 128; ++y)
2923 if(i)
2924 { /* Set up black texture with 2x2 texel white spot in the middle */
2925 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2926 for (x = 0; x < 128; ++x)
2928 *ptr++ = D3DCOLOR_ARGB(0xff, x * 2, y * 2, 0);
2931 else
2932 { /* Set up a displacement map which points away from the center parallel to the closest axis.
2933 * (if multiplied with bumpenvmat)
2935 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2936 for (x = 0; x < 128; ++x)
2938 if(abs(x-64)>abs(y-64))
2940 if(x < 64)
2941 *ptr++ = 0xc000;
2942 else
2943 *ptr++ = 0x4000;
2945 else
2947 if(y < 64)
2948 *ptr++ = 0x0040;
2949 else
2950 *ptr++ = 0x00c0;
2955 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
2956 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2958 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
2959 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2961 /* Disable texture filtering */
2962 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2963 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2964 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2965 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2967 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2968 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
2969 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2970 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
2974 /* Test the behavior of the texbem instruction with normal 2D and projective
2975 * 2D textures. */
2976 static void texbem_test(void)
2978 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
2979 /* Use asymmetric matrix to test loading. */
2980 float bumpenvmat[4] = {0.0f, 0.5f, -0.5f, 0.0f};
2981 IDirect3DPixelShader9 *pixel_shader = NULL;
2982 IDirect3DTexture9 *texture1, *texture2;
2983 IDirect3DTexture9 *texture = NULL;
2984 D3DLOCKED_RECT locked_rect;
2985 IDirect3DDevice9 *device;
2986 IDirect3D9 *d3d;
2987 ULONG refcount;
2988 D3DCAPS9 caps;
2989 DWORD color;
2990 HWND window;
2991 HRESULT hr;
2992 int i;
2994 static const DWORD pixel_shader_code[] =
2996 0xffff0101, /* ps_1_1*/
2997 0x00000042, 0xb00f0000, /* tex t0*/
2998 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
2999 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
3000 0x0000ffff
3002 static const DWORD double_texbem_code[] =
3004 0xffff0103, /* ps_1_3 */
3005 0x00000042, 0xb00f0000, /* tex t0 */
3006 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
3007 0x00000042, 0xb00f0002, /* tex t2 */
3008 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
3009 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
3010 0x0000ffff /* end */
3012 static const float quad[][7] =
3014 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
3015 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
3016 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
3017 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
3019 static const float quad_proj[][9] =
3021 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
3022 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
3023 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
3024 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
3026 static const float double_quad[] =
3028 -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3029 -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3030 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3031 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3033 static const D3DVERTEXELEMENT9 decl_elements[][4] =
3036 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3037 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3038 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
3039 D3DDECL_END()
3042 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3043 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3044 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
3045 D3DDECL_END()
3049 window = create_window();
3050 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3051 ok(!!d3d, "Failed to create a D3D object.\n");
3052 if (!(device = create_device(d3d, window, window, TRUE)))
3054 skip("Failed to create a D3D device, skipping tests.\n");
3055 goto done;
3058 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3059 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3060 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
3062 skip("No ps_1_1 support, skipping tests.\n");
3063 IDirect3DDevice9_Release(device);
3064 goto done;
3067 generate_bumpmap_textures(device);
3069 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
3070 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
3071 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
3072 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
3073 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
3075 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
3076 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
3078 for(i=0; i<2; i++)
3080 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
3081 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
3083 if(i)
3085 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
3086 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
3089 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
3090 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
3091 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
3092 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
3094 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
3095 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
3096 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
3097 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3099 hr = IDirect3DDevice9_BeginScene(device);
3100 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
3102 if(!i)
3103 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
3104 else
3105 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
3106 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
3108 hr = IDirect3DDevice9_EndScene(device);
3109 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
3111 /* The Window 8 testbot (WARP) seems to use the transposed
3112 * D3DTSS_BUMPENVMAT matrix. */
3113 color = getPixelColor(device, 160, 240);
3114 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00007e00, 4)),
3115 "Got unexpected color 0x%08x.\n", color);
3116 color = getPixelColor(device, 480, 240);
3117 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00fe7e00, 4)),
3118 "Got unexpected color 0x%08x.\n", color);
3119 color = getPixelColor(device, 320, 120);
3120 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x0080fe00, 4)),
3121 "Got unexpected color 0x%08x.\n", color);
3122 color = getPixelColor(device, 320, 360);
3123 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00800000, 4)),
3124 "Got unexpected color 0x%08x.\n", color);
3126 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3127 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3129 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3130 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3131 IDirect3DPixelShader9_Release(pixel_shader);
3133 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3134 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
3135 IDirect3DVertexDeclaration9_Release(vertex_declaration);
3138 /* clean up */
3139 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
3140 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
3142 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3143 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
3145 for(i=0; i<2; i++)
3147 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
3148 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
3149 IDirect3DTexture9_Release(texture); /* For the GetTexture */
3150 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
3151 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
3152 IDirect3DTexture9_Release(texture);
3155 /* Test double texbem */
3156 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
3157 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
3158 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
3159 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
3160 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
3161 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
3162 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
3163 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
3165 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
3166 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3167 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
3168 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
3170 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3171 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3173 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
3174 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3175 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
3176 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
3177 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
3178 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3181 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
3182 #define tex 0x00ff0000
3183 #define tex1 0x0000ff00
3184 #define origin 0x000000ff
3185 static const DWORD pixel_data[] = {
3186 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3187 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3188 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3189 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3190 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
3191 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3192 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3193 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3195 #undef tex1
3196 #undef tex2
3197 #undef origin
3199 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
3200 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3201 for(i = 0; i < 8; i++) {
3202 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
3204 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
3205 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3208 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3209 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3210 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
3211 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3212 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
3213 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3214 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
3215 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3216 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
3217 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
3218 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
3219 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
3221 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
3222 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
3223 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
3224 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3225 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
3226 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3227 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
3228 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3229 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
3230 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3232 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
3233 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
3234 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
3235 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3236 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
3237 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3238 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
3239 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3240 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
3241 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3243 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3244 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3245 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3246 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3247 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3248 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3249 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3250 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3251 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3252 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3253 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3254 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3255 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3256 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3257 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3258 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3260 hr = IDirect3DDevice9_BeginScene(device);
3261 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3262 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
3263 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
3264 hr = IDirect3DDevice9_EndScene(device);
3265 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3266 /* The Window 8 testbot (WARP) seems to use the transposed
3267 * D3DTSS_BUMPENVMAT matrix. */
3268 color = getPixelColor(device, 320, 240);
3269 ok(color_match(color, 0x00ffff00, 1) || broken(color_match(color, 0x0000ffff, 1)),
3270 "Got unexpected color 0x%08x.\n", color);
3272 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3273 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3275 IDirect3DPixelShader9_Release(pixel_shader);
3276 IDirect3DTexture9_Release(texture);
3277 IDirect3DTexture9_Release(texture1);
3278 IDirect3DTexture9_Release(texture2);
3279 refcount = IDirect3DDevice9_Release(device);
3280 ok(!refcount, "Device has %u references left.\n", refcount);
3281 done:
3282 IDirect3D9_Release(d3d);
3283 DestroyWindow(window);
3286 static void z_range_test(void)
3288 IDirect3DVertexShader9 *shader;
3289 IDirect3DDevice9 *device;
3290 IDirect3D9 *d3d;
3291 ULONG refcount;
3292 D3DCAPS9 caps;
3293 DWORD color;
3294 HWND window;
3295 HRESULT hr;
3297 static const struct
3299 struct vec3 position;
3300 DWORD diffuse;
3302 quad[] =
3304 {{-1.0f, 0.0f, 1.1f}, 0xffff0000},
3305 {{-1.0f, 1.0f, 1.1f}, 0xffff0000},
3306 {{ 1.0f, 0.0f, -1.1f}, 0xffff0000},
3307 {{ 1.0f, 1.0f, -1.1f}, 0xffff0000},
3309 quad2[] =
3311 {{-1.0f, 0.0f, 1.1f}, 0xff0000ff},
3312 {{-1.0f, 1.0f, 1.1f}, 0xff0000ff},
3313 {{ 1.0f, 0.0f, -1.1f}, 0xff0000ff},
3314 {{ 1.0f, 1.0f, -1.1f}, 0xff0000ff},
3316 static const struct
3318 struct vec4 position;
3319 DWORD diffuse;
3321 quad3[] =
3323 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xffffff00},
3324 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xffffff00},
3325 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xffffff00},
3326 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xffffff00},
3328 quad4[] =
3330 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xff00ff00},
3331 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xff00ff00},
3332 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xff00ff00},
3333 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xff00ff00},
3335 static const DWORD shader_code[] =
3337 0xfffe0101, /* vs_1_1 */
3338 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
3339 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
3340 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
3341 0x0000ffff /* end */
3343 static const float color_const_1[] = {1.0f, 0.0f, 0.0f, 1.0f};
3344 static const float color_const_2[] = {0.0f, 0.0f, 1.0f, 1.0f};
3346 window = create_window();
3347 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3348 ok(!!d3d, "Failed to create a D3D object.\n");
3349 if (!(device = create_device(d3d, window, window, TRUE)))
3351 skip("Failed to create a D3D device, skipping tests.\n");
3352 goto done;
3355 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3356 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3358 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
3359 * then call Present. Then clear the color buffer to make sure it has some defined content
3360 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
3361 * by the depth value. */
3362 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75f, 0);
3363 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3364 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3365 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
3366 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
3367 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3369 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3370 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
3371 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
3372 ok(SUCCEEDED(hr), "Failed to enable clipping, hr %#x.\n", hr);
3373 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3374 ok(SUCCEEDED(hr), "Failed to enable z test, hr %#x.\n", hr);
3375 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3376 ok(SUCCEEDED(hr), "Failed to disable z writes, hr %#x.\n", hr);
3377 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3378 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3379 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3380 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
3382 hr = IDirect3DDevice9_BeginScene(device);
3383 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3385 /* Test the untransformed vertex path */
3386 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
3387 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3388 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
3389 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3390 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
3391 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3393 /* Test the transformed vertex path */
3394 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
3395 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
3397 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
3398 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3399 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3400 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3401 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
3402 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3404 hr = IDirect3DDevice9_EndScene(device);
3405 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3407 /* Do not test the exact corner pixels, but go pretty close to them */
3409 /* Clipped because z > 1.0 */
3410 color = getPixelColor(device, 28, 238);
3411 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3412 color = getPixelColor(device, 28, 241);
3413 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
3414 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3415 else
3416 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
3418 /* Not clipped, > z buffer clear value(0.75).
3420 * On the r500 driver on Windows D3DCMP_GREATER and D3DCMP_GREATEREQUAL are broken for depth
3421 * values > 0.5. The range appears to be distorted, apparently an incoming value of ~0.875 is
3422 * equal to a stored depth buffer value of 0.5. */
3423 color = getPixelColor(device, 31, 238);
3424 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3425 color = getPixelColor(device, 31, 241);
3426 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
3427 color = getPixelColor(device, 100, 238);
3428 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
3429 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3430 color = getPixelColor(device, 100, 241);
3431 ok(color_match(color, 0x00ffff00, 0) || broken(color_match(color, 0x00ffffff, 0)),
3432 "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
3434 /* Not clipped, < z buffer clear value */
3435 color = getPixelColor(device, 104, 238);
3436 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3437 color = getPixelColor(device, 104, 241);
3438 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
3439 color = getPixelColor(device, 318, 238);
3440 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3441 color = getPixelColor(device, 318, 241);
3442 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
3444 /* Clipped because z < 0.0 */
3445 color = getPixelColor(device, 321, 238);
3446 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3447 color = getPixelColor(device, 321, 241);
3448 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
3449 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3450 else
3451 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3453 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3454 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
3456 /* Test the shader path */
3457 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
3459 skip("Vertex shaders not supported, skipping tests.\n");
3460 IDirect3DDevice9_Release(device);
3461 goto done;
3463 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
3464 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
3466 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
3467 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3469 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3470 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
3471 hr = IDirect3DDevice9_SetVertexShader(device, shader);
3472 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
3474 hr = IDirect3DDevice9_BeginScene(device);
3475 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3477 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, color_const_1, 1);
3478 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
3479 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
3480 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3482 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
3483 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3484 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, color_const_2, 1);
3485 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
3486 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
3487 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3489 hr = IDirect3DDevice9_EndScene(device);
3490 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3492 IDirect3DVertexShader9_Release(shader);
3494 /* Z < 1.0 */
3495 color = getPixelColor(device, 28, 238);
3496 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3498 /* 1.0 < z < 0.75 */
3499 color = getPixelColor(device, 31, 238);
3500 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3501 color = getPixelColor(device, 100, 238);
3502 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
3503 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3505 /* 0.75 < z < 0.0 */
3506 color = getPixelColor(device, 104, 238);
3507 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3508 color = getPixelColor(device, 318, 238);
3509 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3511 /* 0.0 < z */
3512 color = getPixelColor(device, 321, 238);
3513 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3515 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3516 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
3518 refcount = IDirect3DDevice9_Release(device);
3519 ok(!refcount, "Device has %u references left.\n", refcount);
3520 done:
3521 IDirect3D9_Release(d3d);
3522 DestroyWindow(window);
3525 static void fill_surface(IDirect3DSurface9 *surface, DWORD color, DWORD flags)
3527 D3DSURFACE_DESC desc;
3528 D3DLOCKED_RECT l;
3529 HRESULT hr;
3530 unsigned int x, y;
3531 DWORD *mem;
3533 memset(&desc, 0, sizeof(desc));
3534 memset(&l, 0, sizeof(l));
3535 hr = IDirect3DSurface9_GetDesc(surface, &desc);
3536 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
3537 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, flags);
3538 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
3539 if(FAILED(hr)) return;
3541 for(y = 0; y < desc.Height; y++)
3543 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
3544 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
3546 mem[x] = color;
3549 hr = IDirect3DSurface9_UnlockRect(surface);
3550 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
3553 static void stretchrect_test(void)
3555 IDirect3DSurface9 *surf_tex_rt32, *surf_tex_rt64, *surf_tex_rt_dest64, *surf_tex_rt_dest640_480;
3556 IDirect3DSurface9 *surf_offscreen32, *surf_offscreen64, *surf_offscreen_dest64;
3557 IDirect3DTexture9 *tex_rt32, *tex_rt64, *tex_rt_dest64, *tex_rt_dest640_480;
3558 IDirect3DSurface9 *surf_tex32, *surf_tex64, *surf_tex_dest64;
3559 IDirect3DSurface9 *surf_rt32, *surf_rt64, *surf_rt_dest64;
3560 IDirect3DTexture9 *tex32, *tex64, *tex_dest64;
3561 IDirect3DSurface9 *surf_temp32, *surf_temp64;
3562 IDirect3DSurface9 *backbuffer;
3563 IDirect3DDevice9 *device;
3564 IDirect3D9 *d3d;
3565 D3DCOLOR color;
3566 ULONG refcount;
3567 HWND window;
3568 HRESULT hr;
3570 static const RECT src_rect = {0, 0, 640, 480};
3571 static const RECT src_rect_flipy = {0, 480, 640, 0};
3572 static const RECT dst_rect = {0, 0, 640, 480};
3573 static const RECT dst_rect_flipy = {0, 480, 640, 0};
3574 static const RECT src_rect64 = {0, 0, 64, 64};
3575 static const RECT src_rect64_flipy = {0, 64, 64, 0};
3576 static const RECT dst_rect64 = {0, 0, 64, 64};
3577 static const RECT dst_rect64_flipy = {0, 64, 64, 0};
3579 window = create_window();
3580 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3581 ok(!!d3d, "Failed to create a D3D object.\n");
3582 if (!(device = create_device(d3d, window, window, TRUE)))
3584 skip("Failed to create a D3D device, skipping tests.\n");
3585 goto done;
3588 /* Create our temporary surfaces in system memory. */
3589 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
3590 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
3591 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3592 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
3593 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
3594 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3596 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT. */
3597 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
3598 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
3599 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3600 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
3601 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
3602 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3603 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
3604 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
3605 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3607 /* Create render target surfaces. */
3608 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32,
3609 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
3610 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
3611 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64,
3612 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
3613 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
3614 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64,
3615 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
3616 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
3617 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
3618 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
3620 /* Create render target textures. */
3621 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET,
3622 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
3623 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3624 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET,
3625 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
3626 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3627 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET,
3628 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
3629 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3630 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET,
3631 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
3632 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3633 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
3634 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3635 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
3636 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3637 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
3638 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3639 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
3640 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3642 /* Create regular textures in D3DPOOL_DEFAULT. */
3643 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
3644 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3645 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
3646 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3647 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
3648 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3649 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
3650 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3651 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
3652 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3653 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
3654 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3656 /**********************************************************************
3657 * Tests for when the source parameter is an offscreen plain surface. *
3658 **********************************************************************/
3660 /* Fill the offscreen 64x64 surface with green. */
3661 fill_surface(surf_offscreen64, 0xff00ff00, 0);
3663 /* offscreenplain ==> offscreenplain, same size. */
3664 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, D3DTEXF_NONE);
3665 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3666 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
3667 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
3668 /* Blit without scaling. */
3669 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3670 surf_offscreen_dest64, &dst_rect64, D3DTEXF_NONE);
3671 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3672 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3673 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy,
3674 surf_offscreen_dest64, &dst_rect64, D3DTEXF_NONE);
3675 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3676 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3677 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3678 surf_offscreen_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3679 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3681 /* offscreenplain ==> rendertarget texture, same size. */
3682 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3683 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3684 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3685 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3686 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3687 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3688 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
3689 /* Blit without scaling. */
3690 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3691 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3692 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3693 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3694 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy,
3695 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3696 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3697 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3698 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3699 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3700 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3702 /* offscreenplain ==> rendertarget surface, same size. */
3703 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3704 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3705 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3706 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
3707 /* Blit without scaling. */
3708 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3709 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3710 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3711 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3712 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy,
3713 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3714 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3715 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3716 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3717 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3718 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3720 /* offscreenplain ==> texture, same size (should fail). */
3721 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3722 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3724 /* Fill the smaller offscreen surface with red. */
3725 fill_surface(surf_offscreen32, 0xffff0000, 0);
3727 /* offscreenplain ==> offscreenplain, scaling (should fail). */
3728 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3729 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3731 /* offscreenplain ==> rendertarget texture, scaling. */
3732 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3733 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3734 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3735 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3736 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3737 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3738 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3740 /* offscreenplain ==> rendertarget surface, scaling. */
3741 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3742 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3743 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3744 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3746 /* offscreenplain ==> texture, scaling (should fail). */
3747 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3748 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3750 /*************************************************************
3751 * Tests for when the source parameter is a regular texture. *
3752 *************************************************************/
3754 /* Fill the surface of the regular texture with blue. */
3755 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT. */
3756 fill_surface(surf_temp64, 0xff0000ff, 0);
3757 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
3758 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3760 /* texture ==> offscreenplain, same size. */
3761 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3762 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3764 /* texture ==> rendertarget texture, same size. */
3765 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3766 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3767 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3768 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3769 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3770 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3771 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
3772 /* Blit without scaling. */
3773 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3774 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3775 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3776 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3777 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy,
3778 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3779 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3780 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3781 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3782 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3783 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3785 /* texture ==> rendertarget surface, same size. */
3786 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3787 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3788 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3789 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
3790 /* Blit without scaling. */
3791 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3792 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3793 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3794 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3795 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy,
3796 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3797 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3798 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3799 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3800 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3801 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3803 /* texture ==> texture, same size (should fail). */
3804 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3805 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3807 /* Fill the surface of the smaller regular texture with red. */
3808 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT. */
3809 fill_surface(surf_temp32, 0xffff0000, 0);
3810 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
3811 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3813 /* texture ==> offscreenplain, scaling (should fail). */
3814 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3815 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3817 /* texture ==> rendertarget texture, scaling. */
3818 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3819 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3820 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3821 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3822 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3823 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3824 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3826 /* texture ==> rendertarget surface, scaling. */
3827 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3828 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3829 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3830 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3832 /* texture ==> texture, scaling (should fail). */
3833 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3834 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3836 /******************************************************************
3837 * Tests for when the source parameter is a rendertarget texture. *
3838 ******************************************************************/
3840 /* Fill the surface of the rendertarget texture with white. */
3841 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT. */
3842 fill_surface(surf_temp64, 0xffffffff, 0);
3843 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
3844 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3846 /* rendertarget texture ==> offscreenplain, same size. */
3847 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3848 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3850 /* rendertarget texture ==> rendertarget texture, same size. */
3851 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3852 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3853 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3854 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3855 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3856 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3857 ok(color == 0xffffffff, "Got unexpected color 0x%08x.\n", color);
3858 /* Blit without scaling. */
3859 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3860 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3861 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3862 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3863 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy,
3864 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3865 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3866 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3867 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3868 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3869 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3871 /* rendertarget texture ==> rendertarget surface, same size. */
3872 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3873 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3874 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3875 ok(color == 0xffffffff, "Got unexpected color 0x%08x.\n", color);
3876 /* Blit without scaling. */
3877 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3878 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3879 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3880 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3881 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy,
3882 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3883 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3884 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3885 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3886 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3887 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3889 /* rendertarget texture ==> texture, same size (should fail). */
3890 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3891 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3893 /* Fill the surface of the smaller rendertarget texture with red. */
3894 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT. */
3895 fill_surface(surf_temp32, 0xffff0000, 0);
3896 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
3897 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3899 /* rendertarget texture ==> offscreenplain, scaling (should fail). */
3900 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3901 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3903 /* rendertarget texture ==> rendertarget texture, scaling. */
3904 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3905 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3906 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3907 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3908 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3909 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3910 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3912 /* rendertarget texture ==> rendertarget surface, scaling. */
3913 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3914 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3915 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3916 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3918 /* rendertarget texture ==> texture, scaling (should fail). */
3919 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3920 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3922 /******************************************************************
3923 * Tests for when the source parameter is a rendertarget surface. *
3924 ******************************************************************/
3926 /* Fill the surface of the rendertarget surface with black. */
3927 fill_surface(surf_rt64, 0xff000000, 0);
3929 /* rendertarget texture ==> offscreenplain, same size. */
3930 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3931 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3933 /* rendertarget surface ==> rendertarget texture, same size. */
3934 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3935 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3936 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3937 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3938 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3939 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3940 ok(color == 0xff000000, "Got unexpected color 0x%08x.\n", color);
3941 /* Blit without scaling. */
3942 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3943 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3944 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3945 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3946 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy,
3947 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3948 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3949 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3950 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3951 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3952 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3954 /* rendertarget surface ==> rendertarget surface, same size. */
3955 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3956 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3957 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3958 ok(color == 0xff000000, "Got unexpected color 0x%08x.\n", color);
3959 /* Blit without scaling. */
3960 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3961 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3962 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3963 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3964 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy,
3965 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3966 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3967 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3968 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3969 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3970 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3972 /* rendertarget surface ==> texture, same size (should fail). */
3973 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3974 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3976 /* Fill the surface of the smaller rendertarget texture with red. */
3977 fill_surface(surf_rt32, 0xffff0000, 0);
3979 /* rendertarget surface ==> offscreenplain, scaling (should fail). */
3980 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3981 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3983 /* rendertarget surface ==> rendertarget texture, scaling. */
3984 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3985 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3986 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3987 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3988 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3989 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3990 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3992 /* rendertarget surface ==> rendertarget surface, scaling. */
3993 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3994 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3995 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3996 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3998 /* rendertarget surface ==> texture, scaling (should fail). */
3999 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
4000 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4002 /* backbuffer ==> surface tests (no scaling). */
4003 /* Blit with NULL rectangles. */
4004 hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, D3DTEXF_NONE);
4005 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4006 /* Blit without scaling. */
4007 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect,
4008 surf_tex_rt_dest640_480, &dst_rect, D3DTEXF_NONE);
4009 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4010 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
4011 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy,
4012 surf_tex_rt_dest640_480, &dst_rect, D3DTEXF_NONE);
4013 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4014 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
4015 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect,
4016 surf_tex_rt_dest640_480, &dst_rect_flipy, D3DTEXF_NONE);
4017 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4019 /* TODO: Test format conversions. */
4021 IDirect3DSurface9_Release(backbuffer);
4022 IDirect3DSurface9_Release(surf_rt32);
4023 IDirect3DSurface9_Release(surf_rt64);
4024 IDirect3DSurface9_Release(surf_rt_dest64);
4025 IDirect3DSurface9_Release(surf_temp32);
4026 IDirect3DSurface9_Release(surf_temp64);
4027 IDirect3DSurface9_Release(surf_offscreen32);
4028 IDirect3DSurface9_Release(surf_offscreen64);
4029 IDirect3DSurface9_Release(surf_offscreen_dest64);
4030 IDirect3DSurface9_Release(surf_tex_rt32);
4031 IDirect3DTexture9_Release(tex_rt32);
4032 IDirect3DSurface9_Release(surf_tex_rt64);
4033 IDirect3DTexture9_Release(tex_rt64);
4034 IDirect3DSurface9_Release(surf_tex_rt_dest64);
4035 IDirect3DTexture9_Release(tex_rt_dest64);
4036 IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
4037 IDirect3DTexture9_Release(tex_rt_dest640_480);
4038 IDirect3DSurface9_Release(surf_tex32);
4039 IDirect3DTexture9_Release(tex32);
4040 IDirect3DSurface9_Release(surf_tex64);
4041 IDirect3DTexture9_Release(tex64);
4042 IDirect3DSurface9_Release(surf_tex_dest64);
4043 IDirect3DTexture9_Release(tex_dest64);
4044 refcount = IDirect3DDevice9_Release(device);
4045 ok(!refcount, "Device has %u references left.\n", refcount);
4046 done:
4047 IDirect3D9_Release(d3d);
4048 DestroyWindow(window);
4051 static void maxmip_test(void)
4053 IDirect3DTexture9 *texture;
4054 IDirect3DSurface9 *surface;
4055 IDirect3DDevice9 *device;
4056 IDirect3D9 *d3d;
4057 D3DCOLOR color;
4058 ULONG refcount;
4059 D3DCAPS9 caps;
4060 HWND window;
4061 HRESULT hr;
4062 DWORD ret;
4064 static const struct
4066 struct
4068 float x, y, z;
4069 float s, t;
4071 v[4];
4073 quads[] =
4076 {-1.0, -1.0, 0.0, 0.0, 0.0},
4077 {-1.0, 0.0, 0.0, 0.0, 1.0},
4078 { 0.0, -1.0, 0.0, 1.0, 0.0},
4079 { 0.0, 0.0, 0.0, 1.0, 1.0},
4082 { 0.0, -1.0, 0.0, 0.0, 0.0},
4083 { 0.0, 0.0, 0.0, 0.0, 1.0},
4084 { 1.0, -1.0, 0.0, 1.0, 0.0},
4085 { 1.0, 0.0, 0.0, 1.0, 1.0},
4088 { 0.0, 0.0, 0.0, 0.0, 0.0},
4089 { 0.0, 1.0, 0.0, 0.0, 1.0},
4090 { 1.0, 0.0, 0.0, 1.0, 0.0},
4091 { 1.0, 1.0, 0.0, 1.0, 1.0},
4094 {-1.0, 0.0, 0.0, 0.0, 0.0},
4095 {-1.0, 1.0, 0.0, 0.0, 1.0},
4096 { 0.0, 0.0, 0.0, 1.0, 0.0},
4097 { 0.0, 1.0, 0.0, 1.0, 1.0},
4101 window = create_window();
4102 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4103 ok(!!d3d, "Failed to create a D3D object.\n");
4104 if (!(device = create_device(d3d, window, window, TRUE)))
4106 skip("Failed to create a D3D device, skipping tests.\n");
4107 goto done;
4110 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4111 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4112 if (!(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP))
4114 skip("No mipmap support, skipping tests.\n");
4115 IDirect3DDevice9_Release(device);
4116 goto done;
4119 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0,
4120 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
4121 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
4123 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4124 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
4125 fill_surface(surface, 0xffff0000, 0);
4126 IDirect3DSurface9_Release(surface);
4127 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
4128 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
4129 fill_surface(surface, 0xff00ff00, 0);
4130 IDirect3DSurface9_Release(surface);
4131 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
4132 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
4133 fill_surface(surface, 0xff0000ff, 0);
4134 IDirect3DSurface9_Release(surface);
4136 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4137 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4138 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4139 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4141 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4142 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4143 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4144 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4146 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
4147 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4149 hr = IDirect3DDevice9_BeginScene(device);
4150 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4152 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
4153 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4154 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
4155 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4157 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
4158 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4159 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
4160 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4162 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4163 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4164 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
4165 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4167 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
4168 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4169 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
4170 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4172 hr = IDirect3DDevice9_EndScene(device);
4173 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4175 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
4176 color = getPixelColor(device, 160, 360);
4177 ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
4178 color = getPixelColor(device, 480, 360);
4179 ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
4180 color = getPixelColor(device, 480, 120);
4181 ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
4182 color = getPixelColor(device, 160, 120);
4183 ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
4184 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4185 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4187 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4188 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4190 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
4191 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4193 hr = IDirect3DDevice9_BeginScene(device);
4194 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4196 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
4197 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4198 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
4199 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4201 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
4202 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4203 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
4204 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4206 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4207 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4208 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
4209 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4211 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
4212 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4213 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
4214 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4216 hr = IDirect3DDevice9_EndScene(device);
4217 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4219 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
4220 * level 3 (> levels in texture) samples from the highest level in the
4221 * texture (level 2). */
4222 color = getPixelColor(device, 160, 360);
4223 ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
4224 color = getPixelColor(device, 480, 360);
4225 ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
4226 color = getPixelColor(device, 480, 120);
4227 ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
4228 color = getPixelColor(device, 160, 120);
4229 ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
4230 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4231 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4233 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
4234 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4236 hr = IDirect3DDevice9_BeginScene(device);
4237 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4239 /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
4240 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4241 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4242 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
4243 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4244 ret = IDirect3DTexture9_SetLOD(texture, 1);
4245 ok(ret == 0, "Got unexpected LOD %u.\n", ret);
4246 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
4247 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4249 /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
4250 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4251 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4252 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
4253 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4254 ret = IDirect3DTexture9_SetLOD(texture, 2);
4255 ok(ret == 1, "Got unexpected LOD %u.\n", ret);
4256 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
4257 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4259 /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
4260 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4261 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4262 ret = IDirect3DTexture9_SetLOD(texture, 1);
4263 ok(ret == 2, "Got unexpected LOD %u.\n", ret);
4264 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
4265 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4267 /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
4268 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4269 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4270 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4271 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4272 ret = IDirect3DTexture9_SetLOD(texture, 1);
4273 ok(ret == 1, "Got unexpected LOD %u.\n", ret);
4274 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
4275 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4277 hr = IDirect3DDevice9_EndScene(device);
4278 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4280 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
4281 * level 3 (> levels in texture) samples from the highest level in the
4282 * texture (level 2). */
4283 color = getPixelColor(device, 160, 360);
4284 ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
4285 color = getPixelColor(device, 480, 360);
4286 ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
4287 color = getPixelColor(device, 480, 120);
4288 ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
4289 color = getPixelColor(device, 160, 120);
4290 ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
4292 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4293 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4295 IDirect3DTexture9_Release(texture);
4296 refcount = IDirect3DDevice9_Release(device);
4297 ok(!refcount, "Device has %u references left.\n", refcount);
4298 done:
4299 IDirect3D9_Release(d3d);
4300 DestroyWindow(window);
4303 static void release_buffer_test(void)
4305 IDirect3DVertexBuffer9 *vb;
4306 IDirect3DIndexBuffer9 *ib;
4307 IDirect3DDevice9 *device;
4308 IDirect3D9 *d3d;
4309 D3DCOLOR color;
4310 ULONG refcount;
4311 HWND window;
4312 HRESULT hr;
4313 BYTE *data;
4314 LONG ref;
4316 static const short indices[] = {3, 4, 5};
4317 static const struct
4319 struct vec3 position;
4320 DWORD diffuse;
4322 quad[] =
4324 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
4325 {{-1.0f, 1.0f, 0.1f}, 0xffff0000},
4326 {{ 1.0f, 1.0f, 0.1f}, 0xffff0000},
4328 {{-1.0f, -1.0f, 0.1f}, 0xff00ff00},
4329 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
4330 {{ 1.0f, 1.0f, 0.1f}, 0xff00ff00},
4333 window = create_window();
4334 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4335 ok(!!d3d, "Failed to create a D3D object.\n");
4336 if (!(device = create_device(d3d, window, window, TRUE)))
4338 skip("Failed to create a D3D device, skipping tests.\n");
4339 goto done;
4342 /* Index and vertex buffers should always be creatable */
4343 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0,
4344 D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &vb, NULL);
4345 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
4346 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
4347 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
4348 memcpy(data, quad, sizeof(quad));
4349 hr = IDirect3DVertexBuffer9_Unlock(vb);
4350 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
4352 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0,
4353 D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
4354 ok(SUCCEEDED(hr), "Failed to create index buffer, hr %#x.\n", hr);
4355 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
4356 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
4357 memcpy(data, indices, sizeof(indices));
4358 hr = IDirect3DIndexBuffer9_Unlock(ib);
4359 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
4361 hr = IDirect3DDevice9_SetIndices(device, ib);
4362 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
4363 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
4364 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
4365 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
4366 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4367 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4368 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4370 /* Now destroy the bound index buffer and draw again */
4371 ref = IDirect3DIndexBuffer9_Release(ib);
4372 ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
4374 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4375 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
4377 hr = IDirect3DDevice9_BeginScene(device);
4378 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4379 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent
4380 * D3D from making assumptions about the indices or vertices. */
4381 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
4382 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4383 hr = IDirect3DDevice9_EndScene(device);
4384 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4386 color = getPixelColor(device, 160, 120);
4387 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1), "Got unexpected color 0x%08x.\n", color);
4388 color = getPixelColor(device, 480, 360);
4389 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1), "Got unexpected color 0x%08x.\n", color);
4391 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4392 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4394 /* Index buffer was already destroyed as part of the test */
4395 IDirect3DVertexBuffer9_Release(vb);
4396 refcount = IDirect3DDevice9_Release(device);
4397 ok(!refcount, "Device has %u references left.\n", refcount);
4398 done:
4399 IDirect3D9_Release(d3d);
4400 DestroyWindow(window);
4403 static void float_texture_test(void)
4405 IDirect3DTexture9 *texture;
4406 IDirect3DDevice9 *device;
4407 D3DLOCKED_RECT lr;
4408 IDirect3D9 *d3d;
4409 ULONG refcount;
4410 float *data;
4411 DWORD color;
4412 HWND window;
4413 HRESULT hr;
4415 static const float quad[] =
4417 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
4418 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
4419 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
4420 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4423 window = create_window();
4424 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4425 ok(!!d3d, "Failed to create a D3D object.\n");
4426 if (!(device = create_device(d3d, window, window, TRUE)))
4428 skip("Failed to create a D3D device, skipping tests.\n");
4429 goto done;
4432 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
4433 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK)
4435 skip("D3DFMT_R32F textures not supported\n");
4436 IDirect3DDevice9_Release(device);
4437 goto done;
4440 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F, D3DPOOL_MANAGED, &texture, NULL);
4441 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
4443 memset(&lr, 0, sizeof(lr));
4444 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4445 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
4446 data = lr.pBits;
4447 *data = 0.0;
4448 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4449 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
4451 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4452 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4453 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
4454 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4456 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4457 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
4459 hr = IDirect3DDevice9_BeginScene(device);
4460 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4461 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4462 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4463 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4464 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4465 hr = IDirect3DDevice9_EndScene(device);
4466 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4468 color = getPixelColor(device, 240, 320);
4469 ok(color == 0x0000ffff, "R32F with value 0.0 has color %08x, expected 0x0000ffff\n", color);
4471 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4472 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4474 IDirect3DTexture9_Release(texture);
4475 refcount = IDirect3DDevice9_Release(device);
4476 ok(!refcount, "Device has %u references left.\n", refcount);
4477 done:
4478 IDirect3D9_Release(d3d);
4479 DestroyWindow(window);
4482 static void g16r16_texture_test(void)
4484 IDirect3DTexture9 *texture;
4485 IDirect3DDevice9 *device;
4486 D3DLOCKED_RECT lr;
4487 IDirect3D9 *d3d;
4488 ULONG refcount;
4489 DWORD *data;
4490 DWORD color;
4491 HWND window;
4492 HRESULT hr;
4494 static const float quad[] =
4496 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
4497 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
4498 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
4499 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4502 window = create_window();
4503 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4504 ok(!!d3d, "Failed to create a D3D object.\n");
4505 if (!(device = create_device(d3d, window, window, TRUE)))
4507 skip("Failed to create a D3D device, skipping tests.\n");
4508 goto done;
4511 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
4512 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK)
4514 skip("D3DFMT_G16R16 textures not supported\n");
4515 IDirect3DDevice9_Release(device);
4516 goto done;
4519 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16, D3DPOOL_MANAGED, &texture, NULL);
4520 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
4522 memset(&lr, 0, sizeof(lr));
4523 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4524 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
4525 data = lr.pBits;
4526 *data = 0x0f00f000;
4527 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4528 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
4530 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4531 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4532 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
4533 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4535 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4536 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
4538 hr = IDirect3DDevice9_BeginScene(device);
4539 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4540 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4541 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4542 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4543 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4544 hr = IDirect3DDevice9_EndScene(device);
4545 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4547 color = getPixelColor(device, 240, 320);
4548 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
4549 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
4551 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4552 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4554 IDirect3DTexture9_Release(texture);
4555 refcount = IDirect3DDevice9_Release(device);
4556 ok(!refcount, "Device has %u references left.\n", refcount);
4557 done:
4558 IDirect3D9_Release(d3d);
4559 DestroyWindow(window);
4562 static void check_rect(IDirect3DDevice9 *device, RECT r, const char *message)
4564 LONG x_coords[2][2] =
4566 {r.left - 1, r.left + 1},
4567 {r.right + 1, r.right - 1},
4569 LONG y_coords[2][2] =
4571 {r.top - 1, r.top + 1},
4572 {r.bottom + 1, r.bottom - 1}
4574 unsigned int i, j, x_side, y_side;
4576 for (i = 0; i < 2; ++i)
4578 for (j = 0; j < 2; ++j)
4580 for (x_side = 0; x_side < 2; ++x_side)
4582 for (y_side = 0; y_side < 2; ++y_side)
4584 unsigned int x = x_coords[i][x_side], y = y_coords[j][y_side];
4585 DWORD color;
4586 DWORD expected = (x_side == 1 && y_side == 1) ? 0x00ffffff : 0;
4588 color = getPixelColor(device, x, y);
4589 ok(color == expected, "%s: Pixel (%d, %d) has color %08x, expected %08x\n",
4590 message, x, y, color, expected);
4597 struct projected_textures_test_run
4599 const char *message;
4600 DWORD flags;
4601 IDirect3DVertexDeclaration9 *decl;
4602 BOOL vs, ps;
4603 RECT rect;
4606 static void projected_textures_test(IDirect3DDevice9 *device,
4607 struct projected_textures_test_run tests[4])
4609 unsigned int i;
4611 static const DWORD vertex_shader[] =
4613 0xfffe0101, /* vs_1_1 */
4614 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4615 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
4616 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4617 0x00000001, 0xe00f0000, 0x90e40001, /* mov oT0, v1 */
4618 0x0000ffff /* end */
4620 static const DWORD pixel_shader[] =
4622 0xffff0103, /* ps_1_3 */
4623 0x00000042, 0xb00f0000, /* tex t0 */
4624 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4625 0x0000ffff /* end */
4627 IDirect3DVertexShader9 *vs = NULL;
4628 IDirect3DPixelShader9 *ps = NULL;
4629 IDirect3D9 *d3d;
4630 D3DCAPS9 caps;
4631 HRESULT hr;
4633 IDirect3DDevice9_GetDirect3D(device, &d3d);
4634 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4635 ok(SUCCEEDED(hr), "GetDeviceCaps failed (%08x)\n", hr);
4636 IDirect3D9_Release(d3d);
4638 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
4640 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader, &vs);
4641 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
4643 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 3))
4645 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader, &ps);
4646 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
4649 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0f, 0);
4650 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4652 hr = IDirect3DDevice9_BeginScene(device);
4653 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4655 for (i = 0; i < 4; ++i)
4657 DWORD value = 0xdeadbeef;
4658 static const float proj_quads[] =
4660 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4661 -1.0f, 0.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4662 0.0f, -1.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4663 0.0f, 0.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4665 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4666 0.0f, 0.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4667 1.0f, -1.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4668 1.0f, 0.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4670 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4671 -1.0f, 1.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4672 0.0f, 0.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4673 0.0f, 1.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4675 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4676 0.0f, 1.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4677 1.0f, 0.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4678 1.0f, 1.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4681 if (tests[i].vs)
4683 if (!vs)
4685 skip("Vertex shaders not supported, skipping\n");
4686 continue;
4688 hr = IDirect3DDevice9_SetVertexShader(device, vs);
4690 else
4691 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4692 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
4693 if (tests[i].ps)
4695 if (!ps)
4697 skip("Pixel shaders not supported, skipping\n");
4698 continue;
4700 hr = IDirect3DDevice9_SetPixelShader(device, ps);
4702 else
4703 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4704 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4706 hr = IDirect3DDevice9_SetVertexDeclaration(device, tests[i].decl);
4707 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4709 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, tests[i].flags);
4710 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4711 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, &value);
4712 ok(SUCCEEDED(hr) && value == tests[i].flags,
4713 "GetTextureStageState returned: hr %08x, value %08x.\n", hr, value);
4715 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
4716 &proj_quads[i * 4 * 7], 7 * sizeof(float));
4717 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4720 hr = IDirect3DDevice9_EndScene(device);
4721 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4723 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4724 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4725 if (vs) IDirect3DVertexShader9_Release(vs);
4726 if (ps) IDirect3DPixelShader9_Release(ps);
4728 for (i = 0; i < 4; ++i)
4730 if ((!tests[i].vs || vs) && (!tests[i].ps || ps))
4731 check_rect(device, tests[i].rect, tests[i].message);
4734 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4735 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4738 static void texture_transform_flags_test(void)
4740 HRESULT hr;
4741 IDirect3D9 *d3d;
4742 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
4743 D3DCAPS9 caps;
4744 IDirect3DTexture9 *texture = NULL;
4745 IDirect3DVolumeTexture9 *volume = NULL;
4746 IDirect3DDevice9 *device;
4747 unsigned int x, y, z;
4748 D3DLOCKED_RECT lr;
4749 D3DLOCKED_BOX lb;
4750 D3DCOLOR color;
4751 ULONG refcount;
4752 HWND window;
4753 UINT w, h;
4754 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3, *decl4;
4756 static const D3DVERTEXELEMENT9 decl_elements[] = {
4757 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4758 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4759 D3DDECL_END()
4761 static const D3DVERTEXELEMENT9 decl_elements2[] = {
4762 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4763 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4764 D3DDECL_END()
4766 static const D3DVERTEXELEMENT9 decl_elements3[] = {
4767 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4768 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4769 D3DDECL_END()
4771 static const D3DVERTEXELEMENT9 decl_elements4[] = {
4772 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4773 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4774 D3DDECL_END()
4776 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
4777 0x00, 0xff, 0x00, 0x00,
4778 0x00, 0x00, 0x00, 0x00,
4779 0x00, 0x00, 0x00, 0x00};
4780 static const D3DMATRIX identity =
4782 1.0f, 0.0f, 0.0f, 0.0f,
4783 0.0f, 1.0f, 0.0f, 0.0f,
4784 0.0f, 0.0f, 1.0f, 0.0f,
4785 0.0f, 0.0f, 0.0f, 1.0f,
4786 }}};
4788 window = create_window();
4789 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4790 ok(!!d3d, "Failed to create a D3D object.\n");
4791 if (!(device = create_device(d3d, window, window, TRUE)))
4793 skip("Failed to create a D3D device, skipping tests.\n");
4794 goto done;
4797 memset(&lr, 0, sizeof(lr));
4798 memset(&lb, 0, sizeof(lb));
4799 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
4800 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK)
4801 fmt = D3DFMT_A16B16G16R16;
4803 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4804 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4805 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
4806 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4807 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
4808 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4809 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements4, &decl4);
4810 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4811 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
4812 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
4813 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
4814 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
4815 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
4816 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
4817 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4818 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
4819 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
4820 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
4821 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
4822 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
4823 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
4824 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
4825 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
4826 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState(D3DTSS_COLOROP) returned %08x\n", hr);
4827 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
4828 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState(D3DTSS_COLORARG1) returned %08x\n", hr);
4829 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4830 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
4831 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4832 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4834 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4835 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
4836 w = min(1024, caps.MaxTextureWidth);
4837 h = min(1024, caps.MaxTextureHeight);
4838 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
4839 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
4840 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4841 if (!texture)
4843 skip("Failed to create the test texture.\n");
4844 IDirect3DDevice9_Release(device);
4845 goto done;
4848 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
4849 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
4850 * 1.0 in red and green for the x and y coords
4852 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4853 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
4854 for(y = 0; y < h; y++) {
4855 for(x = 0; x < w; x++) {
4856 double r_f = (double) y / (double) h;
4857 double g_f = (double) x / (double) w;
4858 if(fmt == D3DFMT_A16B16G16R16) {
4859 unsigned short r, g;
4860 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
4861 r = (unsigned short) (r_f * 65536.0);
4862 g = (unsigned short) (g_f * 65536.0);
4863 dst[0] = r;
4864 dst[1] = g;
4865 dst[2] = 0;
4866 dst[3] = 65535;
4867 } else {
4868 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
4869 unsigned char r = (unsigned char) (r_f * 255.0);
4870 unsigned char g = (unsigned char) (g_f * 255.0);
4871 dst[0] = 0;
4872 dst[1] = g;
4873 dst[2] = r;
4874 dst[3] = 255;
4878 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4879 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
4880 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4881 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4883 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4884 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4885 hr = IDirect3DDevice9_BeginScene(device);
4886 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4887 if(SUCCEEDED(hr))
4889 static const float quad1[] =
4891 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f,
4892 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4893 0.0f, -1.0f, 0.1f, 1.0f, 1.0f,
4894 0.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4896 static const float quad2[] =
4898 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4899 -1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4900 0.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4901 0.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4903 static const float quad3[] =
4905 0.0f, 0.0f, 0.1f, 0.5f, 0.5f,
4906 0.0f, 1.0f, 0.1f, 0.5f, 0.5f,
4907 1.0f, 0.0f, 0.1f, 0.5f, 0.5f,
4908 1.0f, 1.0f, 0.1f, 0.5f, 0.5f,
4910 static const float quad4[] =
4912 320.0f, 480.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4913 320.0f, 240.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4914 640.0f, 480.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4915 640.0f, 240.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4917 D3DMATRIX mat =
4919 0.0f, 0.0f, 0.0f, 0.0f,
4920 0.0f, 0.0f, 0.0f, 0.0f,
4921 0.0f, 0.0f, 0.0f, 0.0f,
4922 0.0f, 0.0f, 0.0f, 0.0f,
4923 }}};
4925 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
4926 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4927 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4928 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4929 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4931 /* What happens with transforms enabled? */
4932 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4933 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4934 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4935 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4937 /* What happens if 4 coords are used, but only 2 given ?*/
4938 U(mat).m[2][0] = 1.0f;
4939 U(mat).m[3][1] = 1.0f;
4940 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4941 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4942 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
4943 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4944 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4945 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4947 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
4948 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
4949 * due to the coords in the vertices. (turns out red, indeed)
4951 memset(&mat, 0, sizeof(mat));
4952 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4953 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4954 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
4955 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4956 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4957 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4958 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4959 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4961 hr = IDirect3DDevice9_EndScene(device);
4962 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4964 color = getPixelColor(device, 160, 360);
4965 ok(color_match(color, 0x00ffff00, 1), "quad 1 has color %08x, expected 0x00ffff00\n", color);
4966 color = getPixelColor(device, 160, 120);
4967 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4968 color = getPixelColor(device, 480, 120);
4969 ok(color_match(color, 0x0000ff00, 1), "quad 3 has color %08x, expected 0x0000ff00\n", color);
4970 color = getPixelColor(device, 480, 360);
4971 ok(color_match(color, 0x00ff0000, 1), "quad 4 has color %08x, expected 0x00ff0000\n", color);
4972 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4973 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4975 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
4976 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4978 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4979 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4980 hr = IDirect3DDevice9_BeginScene(device);
4981 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4982 if(SUCCEEDED(hr))
4984 static const float quad1[] =
4986 -1.0f, -1.0f, 0.1f, 0.8f, 0.2f,
4987 -1.0f, 0.0f, 0.1f, 0.8f, 0.2f,
4988 0.0f, -1.0f, 0.1f, 0.8f, 0.2f,
4989 0.0f, 0.0f, 0.1f, 0.8f, 0.2f,
4991 static const float quad2[] =
4993 -1.0f, 0.0f, 0.1f, 0.5f, 1.0f,
4994 -1.0f, 1.0f, 0.1f, 0.5f, 1.0f,
4995 0.0f, 0.0f, 0.1f, 0.5f, 1.0f,
4996 0.0f, 1.0f, 0.1f, 0.5f, 1.0f,
4998 static const float quad3[] =
5000 0.0f, 0.0f, 0.1f, 0.5f, 1.0f,
5001 0.0f, 1.0f, 0.1f, 0.5f, 1.0f,
5002 1.0f, 0.0f, 0.1f, 0.5f, 1.0f,
5003 1.0f, 1.0f, 0.1f, 0.5f, 1.0f,
5005 static const float quad4[] =
5007 0.0f, -1.0f, 0.1f, 0.8f, 0.2f,
5008 0.0f, 0.0f, 0.1f, 0.8f, 0.2f,
5009 1.0f, -1.0f, 0.1f, 0.8f, 0.2f,
5010 1.0f, 0.0f, 0.1f, 0.8f, 0.2f,
5012 D3DMATRIX mat =
5014 0.0f, 0.0f, 0.0f, 0.0f,
5015 0.0f, 0.0f, 0.0f, 0.0f,
5016 0.0f, 1.0f, 0.0f, 0.0f,
5017 0.0f, 0.0f, 0.0f, 0.0f,
5018 }}};
5020 /* What happens to the default 1 in the 3rd coordinate if it is disabled? */
5021 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5022 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5023 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
5024 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5026 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
5027 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
5029 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
5030 * it behaves like COUNT2 because normal textures require 2 coords. */
5031 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
5032 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5033 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
5034 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
5036 /* Just to be sure, the same as quad2 above */
5037 memset(&mat, 0, sizeof(mat));
5038 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5039 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5040 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
5041 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5042 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
5043 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
5045 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
5046 * used? And what happens to the first? */
5047 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
5048 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5049 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
5050 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
5052 hr = IDirect3DDevice9_EndScene(device);
5053 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
5055 color = getPixelColor(device, 160, 360);
5056 ok(color_match(color, 0x00ff0000, 1), "quad 1 has color %08x, expected 0x00ff0000\n", color);
5057 color = getPixelColor(device, 160, 120);
5058 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
5059 color = getPixelColor(device, 480, 120);
5060 ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
5061 "quad 3 has color %08x, expected 0x00ff8000\n", color);
5062 color = getPixelColor(device, 480, 360);
5063 ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00ff0000, 1),
5064 "quad 4 has color %08x, expected 0x0033cc00\n", color);
5065 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5066 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5068 IDirect3DTexture9_Release(texture);
5070 /* Test projected textures, without any fancy matrices */
5071 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
5072 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5073 if (SUCCEEDED(hr))
5075 struct projected_textures_test_run projected_tests_1[4] =
5078 "D3DTTFF_COUNT4 | D3DTTFF_PROJECTED - bottom left",
5079 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED,
5080 decl3,
5081 FALSE, TRUE,
5082 {120, 300, 240, 390},
5085 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED - bottom right",
5086 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
5087 decl3,
5088 FALSE, TRUE,
5089 {400, 360, 480, 420},
5091 /* Try with some invalid values */
5093 "0xffffffff (draws like COUNT4 | PROJECTED) - top left",
5094 0xffffffff,
5095 decl3,
5096 FALSE, TRUE,
5097 {120, 60, 240, 150}
5100 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (draws non-projected) - top right",
5101 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
5102 decl4,
5103 FALSE, TRUE,
5104 {340, 210, 360, 225},
5107 struct projected_textures_test_run projected_tests_2[4] =
5110 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED, texcoord has 4 components) - bottom left",
5111 D3DTTFF_PROJECTED,
5112 decl3,
5113 FALSE, TRUE,
5114 {120, 300, 240, 390},
5117 "D3DTTFF_PROJECTED (like COUNT3 | PROJECTED, texcoord has only 3 components) - bottom right",
5118 D3DTTFF_PROJECTED,
5119 decl,
5120 FALSE, TRUE,
5121 {400, 360, 480, 420},
5124 "0xffffffff (like COUNT3 | PROJECTED, texcoord has only 3 components) - top left",
5125 0xffffffff,
5126 decl,
5127 FALSE, TRUE,
5128 {80, 120, 160, 180},
5131 "D3DTTFF_COUNT1 (draws non-projected) - top right",
5132 D3DTTFF_COUNT1,
5133 decl4,
5134 FALSE, TRUE,
5135 {340, 210, 360, 225},
5138 struct projected_textures_test_run projected_tests_3[4] =
5141 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom left",
5142 D3DTTFF_PROJECTED,
5143 decl3,
5144 TRUE, FALSE,
5145 {120, 300, 240, 390},
5148 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom right",
5149 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
5150 decl3,
5151 TRUE, TRUE,
5152 {440, 300, 560, 390},
5155 "0xffffffff (like COUNT4 | PROJECTED) - top left",
5156 0xffffffff,
5157 decl3,
5158 TRUE, TRUE,
5159 {120, 60, 240, 150},
5162 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - top right",
5163 D3DTTFF_PROJECTED,
5164 decl3,
5165 FALSE, FALSE,
5166 {440, 60, 560, 150},
5170 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
5171 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5173 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5174 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
5175 for(x = 0; x < 4; x++) {
5176 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
5178 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5179 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
5180 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5181 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
5183 projected_textures_test(device, projected_tests_1);
5184 projected_textures_test(device, projected_tests_2);
5185 projected_textures_test(device, projected_tests_3);
5187 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5188 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
5189 IDirect3DTexture9_Release(texture);
5192 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
5193 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5194 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
5195 * Thus watch out if sampling from texels between 0 and 1.
5197 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
5198 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
5199 "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
5200 if(!volume) {
5201 skip("Failed to create a volume texture\n");
5202 goto out;
5205 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
5206 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
5207 for(z = 0; z < 32; z++) {
5208 for(y = 0; y < 32; y++) {
5209 for(x = 0; x < 32; x++) {
5210 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
5211 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
5212 float r_f = (float) x / 31.0;
5213 float g_f = (float) y / 31.0;
5214 float b_f = (float) z / 31.0;
5216 if(fmt == D3DFMT_A16B16G16R16) {
5217 unsigned short *mem_s = mem;
5218 mem_s[0] = r_f * 65535.0;
5219 mem_s[1] = g_f * 65535.0;
5220 mem_s[2] = b_f * 65535.0;
5221 mem_s[3] = 65535;
5222 } else {
5223 unsigned char *mem_c = mem;
5224 mem_c[0] = b_f * 255.0;
5225 mem_c[1] = g_f * 255.0;
5226 mem_c[2] = r_f * 255.0;
5227 mem_c[3] = 255;
5232 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
5233 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
5235 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
5236 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
5238 hr = IDirect3DDevice9_BeginScene(device);
5239 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
5240 if(SUCCEEDED(hr))
5242 static const float quad1[] =
5244 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5245 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5246 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5247 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5249 static const float quad2[] =
5251 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5252 -1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5253 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5254 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5256 static const float quad3[] =
5258 0.0f, 0.0f, 0.1f, 0.0f, 0.0f,
5259 0.0f, 1.0f, 0.1f, 0.0f, 0.0f,
5260 1.0f, 0.0f, 0.1f, 0.0f, 0.0f,
5261 1.0f, 1.0f, 0.1f, 0.0f, 0.0f,
5263 static const float quad4[] =
5265 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5266 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5267 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5268 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5270 D3DMATRIX mat =
5272 1.0f, 0.0f, 0.0f, 0.0f,
5273 0.0f, 0.0f, 1.0f, 0.0f,
5274 0.0f, 1.0f, 0.0f, 0.0f,
5275 0.0f, 0.0f, 0.0f, 1.0f,
5276 }}};
5277 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5278 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5280 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
5281 * values
5283 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5284 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5285 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
5286 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5287 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5288 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5290 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
5291 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
5292 * otherwise the w will be missing(blue).
5293 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
5294 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3. */
5295 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
5296 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5297 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5298 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5300 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
5301 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
5302 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5303 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
5304 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5305 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5306 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5307 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
5308 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5310 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
5311 * disable. ATI extends it up to the amount of values needed for the volume texture
5313 memset(&mat, 0, sizeof(mat));
5314 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5315 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5316 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
5317 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5318 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5319 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5320 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5321 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5323 hr = IDirect3DDevice9_EndScene(device);
5324 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
5327 color = getPixelColor(device, 160, 360);
5328 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
5329 color = getPixelColor(device, 160, 120);
5330 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
5331 "quad 2 has color %08x, expected 0x00ffff00\n", color);
5332 color = getPixelColor(device, 480, 120);
5333 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
5334 color = getPixelColor(device, 480, 360);
5335 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
5337 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5338 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5340 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
5341 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5342 hr = IDirect3DDevice9_BeginScene(device);
5343 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
5344 if(SUCCEEDED(hr))
5346 static const float quad1[] =
5348 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5349 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5350 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5351 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5353 static const float quad2[] =
5355 -1.0f, 0.0f, 0.1f,
5356 -1.0f, 1.0f, 0.1f,
5357 0.0f, 0.0f, 0.1f,
5358 0.0f, 1.0f, 0.1f,
5360 static const float quad3[] =
5362 0.0f, 0.0f, 0.1f, 1.0f,
5363 0.0f, 1.0f, 0.1f, 1.0f,
5364 1.0f, 0.0f, 0.1f, 1.0f,
5365 1.0f, 1.0f, 0.1f, 1.0f,
5367 static const D3DMATRIX mat =
5369 0.0f, 0.0f, 0.0f, 0.0f,
5370 0.0f, 0.0f, 0.0f, 0.0f,
5371 0.0f, 0.0f, 0.0f, 0.0f,
5372 0.0f, 1.0f, 0.0f, 0.0f,
5373 }}};
5374 static const D3DMATRIX mat2 =
5376 0.0f, 0.0f, 0.0f, 1.0f,
5377 1.0f, 0.0f, 0.0f, 0.0f,
5378 0.0f, 1.0f, 0.0f, 0.0f,
5379 0.0f, 0.0f, 1.0f, 0.0f,
5380 }}};
5381 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5382 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5384 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
5385 * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
5386 * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
5387 * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
5388 * 4th *input* coordinate.
5390 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5391 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5392 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
5393 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5394 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5395 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5397 /* None passed */
5398 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
5399 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5400 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5401 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5402 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5403 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5405 /* 4 used, 1 passed */
5406 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5407 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5408 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat2);
5409 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5410 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
5411 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5413 hr = IDirect3DDevice9_EndScene(device);
5414 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
5416 color = getPixelColor(device, 160, 360);
5417 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
5418 color = getPixelColor(device, 160, 120);
5419 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
5420 color = getPixelColor(device, 480, 120);
5421 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
5422 /* Quad4: unused */
5424 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5425 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5427 IDirect3DVolumeTexture9_Release(volume);
5429 out:
5430 IDirect3DVertexDeclaration9_Release(decl);
5431 IDirect3DVertexDeclaration9_Release(decl2);
5432 IDirect3DVertexDeclaration9_Release(decl3);
5433 IDirect3DVertexDeclaration9_Release(decl4);
5434 refcount = IDirect3DDevice9_Release(device);
5435 ok(!refcount, "Device has %u references left.\n", refcount);
5436 done:
5437 IDirect3D9_Release(d3d);
5438 DestroyWindow(window);
5441 static void texdepth_test(void)
5443 IDirect3DPixelShader9 *shader;
5444 IDirect3DDevice9 *device;
5445 IDirect3D9 *d3d;
5446 ULONG refcount;
5447 D3DCAPS9 caps;
5448 DWORD color;
5449 HWND window;
5450 HRESULT hr;
5452 static const float texdepth_test_data1[] = { 0.25f, 2.0f, 0.0f, 0.0f};
5453 static const float texdepth_test_data2[] = { 0.25f, 0.5f, 0.0f, 0.0f};
5454 static const float texdepth_test_data3[] = {-1.00f, 0.1f, 0.0f, 0.0f};
5455 static const float texdepth_test_data4[] = {-0.25f, -0.5f, 0.0f, 0.0f};
5456 static const float texdepth_test_data5[] = { 1.00f, -0.1f, 0.0f, 0.0f};
5457 static const float texdepth_test_data6[] = { 1.00f, 0.5f, 0.0f, 0.0f};
5458 static const float texdepth_test_data7[] = { 0.50f, 0.0f, 0.0f, 0.0f};
5459 static const DWORD shader_code[] =
5461 0xffff0104, /* ps_1_4 */
5462 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
5463 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
5464 0x0000fffd, /* phase */
5465 0x00000057, 0x800f0005, /* texdepth r5 */
5466 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
5467 0x0000ffff /* end */
5469 static const float vertex[] =
5471 -1.0f, -1.0f, 0.0f,
5472 -1.0f, 1.0f, 0.0f,
5473 1.0f, -1.0f, 1.0f,
5474 1.0f, 1.0f, 1.0f,
5477 window = create_window();
5478 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5479 ok(!!d3d, "Failed to create a D3D object.\n");
5480 if (!(device = create_device(d3d, window, window, TRUE)))
5482 skip("Failed to create a D3D device, skipping tests.\n");
5483 goto done;
5486 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5487 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5488 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
5490 skip("No ps_1_4 support, skipping tests.\n");
5491 IDirect3DDevice9_Release(device);
5492 goto done;
5495 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5496 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5498 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
5499 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5500 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5501 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
5502 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
5503 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5504 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
5505 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5506 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
5507 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5508 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5509 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
5511 /* Fill the depth buffer with a gradient */
5512 hr = IDirect3DDevice9_BeginScene(device);
5513 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5514 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5515 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5516 hr = IDirect3DDevice9_EndScene(device);
5517 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5519 /* Now perform the actual tests. Same geometry, but with the shader */
5520 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
5521 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5522 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
5523 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5524 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5525 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5527 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
5528 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5529 hr = IDirect3DDevice9_BeginScene(device);
5530 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5531 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5532 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5533 hr = IDirect3DDevice9_EndScene(device);
5534 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5536 color = getPixelColor(device, 158, 240);
5537 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
5538 color = getPixelColor(device, 162, 240);
5539 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
5541 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5542 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5544 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5545 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5547 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
5548 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5549 hr = IDirect3DDevice9_BeginScene(device);
5550 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5551 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5552 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5553 hr = IDirect3DDevice9_EndScene(device);
5554 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5556 color = getPixelColor(device, 318, 240);
5557 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
5558 color = getPixelColor(device, 322, 240);
5559 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
5561 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5562 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5564 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
5565 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5567 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
5568 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5569 hr = IDirect3DDevice9_BeginScene(device);
5570 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5571 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5572 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5573 hr = IDirect3DDevice9_EndScene(device);
5574 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5576 color = getPixelColor(device, 1, 240);
5577 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
5579 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5580 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5582 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
5583 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5585 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
5586 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5587 hr = IDirect3DDevice9_BeginScene(device);
5588 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5589 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5590 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5591 hr = IDirect3DDevice9_EndScene(device);
5592 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5594 color = getPixelColor(device, 318, 240);
5595 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
5596 color = getPixelColor(device, 322, 240);
5597 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
5599 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5600 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5602 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5603 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5605 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
5606 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5607 hr = IDirect3DDevice9_BeginScene(device);
5608 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5609 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5610 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5611 hr = IDirect3DDevice9_EndScene(device);
5612 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5614 color = getPixelColor(device, 1, 240);
5615 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
5617 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5618 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5620 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
5621 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5623 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
5624 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5625 hr = IDirect3DDevice9_BeginScene(device);
5626 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5627 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5628 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5629 hr = IDirect3DDevice9_EndScene(device);
5630 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5632 color = getPixelColor(device, 638, 240);
5633 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
5635 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5636 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5638 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
5639 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5641 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
5642 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5643 hr = IDirect3DDevice9_BeginScene(device);
5644 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5645 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5646 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5647 hr = IDirect3DDevice9_EndScene(device);
5648 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5650 color = getPixelColor(device, 638, 240);
5651 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
5653 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5654 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5656 IDirect3DPixelShader9_Release(shader);
5657 refcount = IDirect3DDevice9_Release(device);
5658 ok(!refcount, "Device has %u references left.\n", refcount);
5659 done:
5660 IDirect3D9_Release(d3d);
5661 DestroyWindow(window);
5664 static void texkill_test(void)
5666 IDirect3DPixelShader9 *shader;
5667 IDirect3DDevice9 *device;
5668 IDirect3D9 *d3d;
5669 ULONG refcount;
5670 D3DCAPS9 caps;
5671 DWORD color;
5672 HWND window;
5673 HRESULT hr;
5675 static const float vertex[] =
5677 /* bottom top right left */
5678 -1.0f, -1.0f, 1.0f, -0.1f, 0.9f, 0.9f, -0.1f,
5679 -1.0f, 1.0f, 1.0f, -0.1f, 0.9f, -0.1f, 0.9f,
5680 1.0f, -1.0f, 0.0f, 0.9f, -0.1f, 0.9f, -0.1f,
5681 1.0f, 1.0f, 0.0f, 0.9f, -0.1f, -0.1f, 0.9f,
5683 static const DWORD shader_code_11[] =
5685 0xffff0101, /* ps_1_1 */
5686 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
5687 0x00000041, 0xb00f0000, /* texkill t0 */
5688 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5689 0x0000ffff /* end */
5691 static const DWORD shader_code_20[] =
5693 0xffff0200, /* ps_2_0 */
5694 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
5695 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
5696 0x01000041, 0xb00f0000, /* texkill t0 */
5697 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
5698 0x0000ffff /* end */
5701 window = create_window();
5702 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5703 ok(!!d3d, "Failed to create a D3D object.\n");
5704 if (!(device = create_device(d3d, window, window, TRUE)))
5706 skip("Failed to create a D3D device, skipping tests.\n");
5707 goto done;
5710 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5711 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5712 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
5714 skip("No ps_1_1 support, skipping tests.\n");
5715 IDirect3DDevice9_Release(device);
5716 goto done;
5719 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
5720 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5721 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
5722 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5724 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5725 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5726 hr = IDirect3DDevice9_BeginScene(device);
5727 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5728 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
5729 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5730 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
5731 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5732 hr = IDirect3DDevice9_EndScene(device);
5733 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5735 color = getPixelColor(device, 63, 46);
5736 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
5737 color = getPixelColor(device, 66, 46);
5738 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
5739 color = getPixelColor(device, 63, 49);
5740 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
5741 color = getPixelColor(device, 66, 49);
5742 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
5744 color = getPixelColor(device, 578, 46);
5745 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5746 color = getPixelColor(device, 575, 46);
5747 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5748 color = getPixelColor(device, 578, 49);
5749 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
5750 color = getPixelColor(device, 575, 49);
5751 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5753 color = getPixelColor(device, 63, 430);
5754 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5755 color = getPixelColor(device, 63, 433);
5756 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5757 color = getPixelColor(device, 66, 433);
5758 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
5759 color = getPixelColor(device, 66, 430);
5760 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5762 color = getPixelColor(device, 578, 430);
5763 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5764 color = getPixelColor(device, 578, 433);
5765 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5766 color = getPixelColor(device, 575, 433);
5767 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
5768 color = getPixelColor(device, 575, 430);
5769 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5771 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5772 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5774 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5775 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5776 IDirect3DPixelShader9_Release(shader);
5778 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5779 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5780 if (FAILED(IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader)))
5782 skip("Failed to create 2.0 test shader, most likely not supported.\n");
5783 IDirect3DDevice9_Release(device);
5784 goto done;
5787 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5788 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5789 hr = IDirect3DDevice9_BeginScene(device);
5790 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5791 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
5792 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5793 hr = IDirect3DDevice9_EndScene(device);
5794 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5796 color = getPixelColor(device, 63, 46);
5797 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
5798 color = getPixelColor(device, 66, 46);
5799 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
5800 color = getPixelColor(device, 63, 49);
5801 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
5802 color = getPixelColor(device, 66, 49);
5803 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
5805 color = getPixelColor(device, 578, 46);
5806 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5807 color = getPixelColor(device, 575, 46);
5808 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5809 color = getPixelColor(device, 578, 49);
5810 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5811 color = getPixelColor(device, 575, 49);
5812 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5814 color = getPixelColor(device, 63, 430);
5815 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5816 color = getPixelColor(device, 63, 433);
5817 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5818 color = getPixelColor(device, 66, 433);
5819 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5820 color = getPixelColor(device, 66, 430);
5821 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5823 color = getPixelColor(device, 578, 430);
5824 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5825 color = getPixelColor(device, 578, 433);
5826 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5827 color = getPixelColor(device, 575, 433);
5828 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5829 color = getPixelColor(device, 575, 430);
5830 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5832 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5833 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5835 IDirect3DPixelShader9_Release(shader);
5836 refcount = IDirect3DDevice9_Release(device);
5837 ok(!refcount, "Device has %u references left.\n", refcount);
5838 done:
5839 IDirect3D9_Release(d3d);
5840 DestroyWindow(window);
5843 static void autogen_mipmap_test(void)
5845 IDirect3DTexture9 *texture = NULL;
5846 IDirect3DSurface9 *surface;
5847 IDirect3DDevice9 *device;
5848 unsigned int x, y;
5849 D3DLOCKED_RECT lr;
5850 IDirect3D9 *d3d;
5851 D3DCOLOR color;
5852 ULONG refcount;
5853 HWND window;
5854 HRESULT hr;
5856 static const RECT r1 = {256, 256, 512, 512};
5857 static const RECT r2 = {512, 256, 768, 512};
5858 static const RECT r3 = {256, 512, 512, 768};
5859 static const RECT r4 = {512, 512, 768, 768};
5860 static const float quad[] =
5862 -0.5f, -0.5f, 0.1f, 0.0f, 0.0f,
5863 -0.5f, 0.5f, 0.1f, 0.0f, 1.0f,
5864 0.5f, -0.5f, 0.1f, 1.0f, 0.0f,
5865 0.5f, 0.5f, 0.1f, 1.0f, 1.0f,
5868 window = create_window();
5869 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5870 ok(!!d3d, "Failed to create a D3D object.\n");
5871 if (!(device = create_device(d3d, window, window, TRUE)))
5873 skip("Failed to create a D3D device, skipping tests.\n");
5874 goto done;
5877 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
5878 D3DFMT_X8R8G8B8, D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK)
5880 skip("No autogenmipmap support.\n");
5881 IDirect3DDevice9_Release(device);
5882 goto done;
5885 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 1.0f, 0);
5886 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5888 /* Make the mipmap big, so that a smaller mipmap is used
5890 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
5891 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
5892 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5894 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5895 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
5896 memset(&lr, 0, sizeof(lr));
5897 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5898 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
5899 for(y = 0; y < 1024; y++) {
5900 for(x = 0; x < 1024; x++) {
5901 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
5902 POINT pt;
5904 pt.x = x;
5905 pt.y = y;
5906 if(PtInRect(&r1, pt)) {
5907 *dst = 0xffff0000;
5908 } else if(PtInRect(&r2, pt)) {
5909 *dst = 0xff00ff00;
5910 } else if(PtInRect(&r3, pt)) {
5911 *dst = 0xff0000ff;
5912 } else if(PtInRect(&r4, pt)) {
5913 *dst = 0xff000000;
5914 } else {
5915 *dst = 0xffffffff;
5919 hr = IDirect3DSurface9_UnlockRect(surface);
5920 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
5921 IDirect3DSurface9_Release(surface);
5923 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5924 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5925 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
5926 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
5927 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5928 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
5930 hr = IDirect3DDevice9_BeginScene(device);
5931 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5932 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5933 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5934 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5935 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5936 hr = IDirect3DDevice9_EndScene(device);
5937 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5938 IDirect3DTexture9_Release(texture);
5940 color = getPixelColor(device, 200, 200);
5941 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
5942 color = getPixelColor(device, 280, 200);
5943 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
5944 color = getPixelColor(device, 360, 200);
5945 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
5946 color = getPixelColor(device, 440, 200);
5947 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5948 color = getPixelColor(device, 200, 270);
5949 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
5950 color = getPixelColor(device, 280, 270);
5951 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
5952 color = getPixelColor(device, 360, 270);
5953 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
5954 color = getPixelColor(device, 440, 270);
5955 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5956 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5957 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5959 refcount = IDirect3DDevice9_Release(device);
5960 ok(!refcount, "Device has %u references left.\n", refcount);
5961 done:
5962 IDirect3D9_Release(d3d);
5963 DestroyWindow(window);
5966 static void test_constant_clamp_vs(void)
5968 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
5969 IDirect3DVertexDeclaration9 *decl;
5970 IDirect3DDevice9 *device;
5971 IDirect3D9 *d3d;
5972 D3DCOLOR color;
5973 ULONG refcount;
5974 D3DCAPS9 caps;
5975 HWND window;
5976 HRESULT hr;
5978 static const DWORD shader_code_11[] =
5980 0xfffe0101, /* vs_1_1 */
5981 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5982 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5983 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5984 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5985 0x0000ffff /* end */
5987 static const DWORD shader_code_11_2[] =
5989 0xfffe0101, /* vs_1_1 */
5990 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
5991 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
5992 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5993 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5994 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5995 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5996 0x0000ffff /* end */
5998 static const DWORD shader_code_20[] =
6000 0xfffe0200, /* vs_2_0 */
6001 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6002 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6003 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
6004 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6005 0x0000ffff /* end */
6007 static const DWORD shader_code_20_2[] =
6009 0xfffe0200, /* vs_2_0 */
6010 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
6011 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
6012 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6013 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6014 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
6015 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6016 0x0000ffff /* end */
6018 static const D3DVERTEXELEMENT9 decl_elements[] =
6020 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6021 D3DDECL_END()
6023 static const float quad1[] =
6025 -1.0f, -1.0f, 0.1f,
6026 -1.0f, 0.0f, 0.1f,
6027 0.0f, -1.0f, 0.1f,
6028 0.0f, 0.0f, 0.1f,
6030 static const float quad2[] =
6032 0.0f, -1.0f, 0.1f,
6033 0.0f, 0.0f, 0.1f,
6034 1.0f, -1.0f, 0.1f,
6035 1.0f, 0.0f, 0.1f,
6037 static const float quad3[] =
6039 0.0f, 0.0f, 0.1f,
6040 0.0f, 1.0f, 0.1f,
6041 1.0f, 0.0f, 0.1f,
6042 1.0f, 1.0f, 0.1f,
6044 static const float quad4[] =
6046 -1.0f, 0.0f, 0.1f,
6047 -1.0f, 1.0f, 0.1f,
6048 0.0f, 0.0f, 0.1f,
6049 0.0f, 1.0f, 0.1f,
6051 static const float test_data_c1[4] = { 1.25f, -0.50f, -1.50f, 1.0f};
6052 static const float test_data_c2[4] = {-0.50f, 1.25f, 2.00f, 1.0f};
6054 window = create_window();
6055 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6056 ok(!!d3d, "Failed to create a D3D object.\n");
6057 if (!(device = create_device(d3d, window, window, TRUE)))
6059 skip("Failed to create a D3D device, skipping tests.\n");
6060 goto done;
6063 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6064 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6065 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
6067 skip("No vs_1_1 support, skipping tests.\n");
6068 IDirect3DDevice9_Release(device);
6069 goto done;
6072 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
6073 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6075 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
6076 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6077 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
6078 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6079 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
6080 if(FAILED(hr)) shader_20 = NULL;
6081 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
6082 if(FAILED(hr)) shader_20_2 = NULL;
6083 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
6084 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6086 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
6087 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
6088 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
6089 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
6090 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6091 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6093 hr = IDirect3DDevice9_BeginScene(device);
6094 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6096 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
6097 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
6098 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
6099 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6101 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
6102 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
6103 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
6104 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6106 if (shader_20)
6108 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
6109 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
6110 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
6111 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6114 if (shader_20_2)
6116 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
6117 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
6118 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
6119 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6122 hr = IDirect3DDevice9_EndScene(device);
6123 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6125 color = getPixelColor(device, 160, 360);
6126 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6127 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
6128 color = getPixelColor(device, 480, 360);
6129 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6130 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
6131 if(shader_20) {
6132 color = getPixelColor(device, 480, 120);
6133 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6134 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
6136 if(shader_20_2) {
6137 color = getPixelColor(device, 160, 120);
6138 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6139 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
6141 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6142 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6144 IDirect3DVertexDeclaration9_Release(decl);
6145 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
6146 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
6147 IDirect3DVertexShader9_Release(shader_11_2);
6148 IDirect3DVertexShader9_Release(shader_11);
6149 refcount = IDirect3DDevice9_Release(device);
6150 ok(!refcount, "Device has %u references left.\n", refcount);
6151 done:
6152 IDirect3D9_Release(d3d);
6153 DestroyWindow(window);
6156 static void constant_clamp_ps_test(void)
6158 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
6159 IDirect3DDevice9 *device;
6160 IDirect3D9 *d3d;
6161 ULONG refcount;
6162 D3DCAPS9 caps;
6163 DWORD color;
6164 HWND window;
6165 HRESULT hr;
6167 static const DWORD shader_code_11[] =
6169 0xffff0101, /* ps_1_1 */
6170 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6171 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6172 0x0000ffff /* end */
6174 static const DWORD shader_code_12[] =
6176 0xffff0102, /* ps_1_2 */
6177 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6178 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6179 0x0000ffff /* end */
6181 /* Skip 1.3 shaders because we have only 4 quads (ok, could make them
6182 * smaller if needed). 1.2 and 1.4 shaders behave the same, so it's
6183 * unlikely that 1.3 shaders are different. During development of this
6184 * test, 1.3 shaders were verified too. */
6185 static const DWORD shader_code_14[] =
6187 0xffff0104, /* ps_1_4 */
6188 /* Try to make one constant local. It gets clamped too, although the
6189 * binary contains the bigger numbers. */
6190 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
6191 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6192 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6193 0x0000ffff /* end */
6195 static const DWORD shader_code_20[] =
6197 0xffff0200, /* ps_2_0 */
6198 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6199 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6200 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6201 0x0000ffff /* end */
6203 static const float quad1[] =
6205 -1.0f, -1.0f, 0.1f,
6206 -1.0f, 0.0f, 0.1f,
6207 0.0f, -1.0f, 0.1f,
6208 0.0f, 0.0f, 0.1f,
6210 static const float quad2[] =
6212 0.0f, -1.0f, 0.1f,
6213 0.0f, 0.0f, 0.1f,
6214 1.0f, -1.0f, 0.1f,
6215 1.0f, 0.0f, 0.1f,
6217 static const float quad3[] =
6219 0.0f, 0.0f, 0.1f,
6220 0.0f, 1.0f, 0.1f,
6221 1.0f, 0.0f, 0.1f,
6222 1.0f, 1.0f, 0.1f,
6224 static const float quad4[] =
6226 -1.0f, 0.0f, 0.1f,
6227 -1.0f, 1.0f, 0.1f,
6228 0.0f, 0.0f, 0.1f,
6229 0.0f, 1.0f, 0.1f,
6231 static const float test_data_c1[4] = { 1.25f, -0.50f, -1.50f, 1.0f};
6232 static const float test_data_c2[4] = {-0.50f, 1.25f, 2.00f, 1.0f};
6234 window = create_window();
6235 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6236 ok(!!d3d, "Failed to create a D3D object.\n");
6237 if (!(device = create_device(d3d, window, window, TRUE)))
6239 skip("Failed to create a D3D device, skipping tests.\n");
6240 goto done;
6243 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6244 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6245 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
6247 skip("No ps_1_4 support, skipping tests.\n");
6248 IDirect3DDevice9_Release(device);
6249 goto done;
6252 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
6253 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6255 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
6256 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6257 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
6258 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6259 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
6260 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6261 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
6262 if(FAILED(hr)) shader_20 = NULL;
6264 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
6265 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6266 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
6267 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6268 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6269 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6271 hr = IDirect3DDevice9_BeginScene(device);
6272 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6274 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
6275 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6276 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
6277 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6279 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
6280 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6281 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
6282 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6284 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
6285 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6286 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
6287 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6289 if (shader_20)
6291 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
6292 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6293 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
6294 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6297 hr = IDirect3DDevice9_EndScene(device);
6298 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6300 color = getPixelColor(device, 160, 360);
6301 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
6302 "quad 1 has color %08x, expected 0x00808000\n", color);
6303 color = getPixelColor(device, 480, 360);
6304 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
6305 "quad 2 has color %08x, expected 0x00808000\n", color);
6306 color = getPixelColor(device, 480, 120);
6307 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
6308 "quad 3 has color %08x, expected 0x00808000\n", color);
6309 if(shader_20) {
6310 color = getPixelColor(device, 160, 120);
6311 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6312 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
6314 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6315 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6317 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
6318 IDirect3DPixelShader9_Release(shader_14);
6319 IDirect3DPixelShader9_Release(shader_12);
6320 IDirect3DPixelShader9_Release(shader_11);
6321 refcount = IDirect3DDevice9_Release(device);
6322 ok(!refcount, "Device has %u references left.\n", refcount);
6323 done:
6324 IDirect3D9_Release(d3d);
6325 DestroyWindow(window);
6328 static void dp2add_ps_test(void)
6330 IDirect3DPixelShader9 *shader_dp2add_sat;
6331 IDirect3DPixelShader9 *shader_dp2add;
6332 IDirect3DDevice9 *device;
6333 IDirect3D9 *d3d;
6334 ULONG refcount;
6335 D3DCAPS9 caps;
6336 DWORD color;
6337 HWND window;
6338 HRESULT hr;
6340 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
6341 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
6342 * source tokens can be constants. So, for this exercise, we move contents of c0 to
6343 * r0 first.
6344 * The result here for the r,g,b components should be roughly 0.5:
6345 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
6346 static const DWORD shader_code_dp2add[] = {
6347 0xffff0200, /* ps_2_0 */
6348 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
6350 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6351 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
6353 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
6354 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6355 0x0000ffff /* end */
6358 /* Test the _sat modifier, too. Result here should be:
6359 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
6360 * _SAT: ==> 1.0
6361 * ADD: (1.0 + -0.5) = 0.5
6363 static const DWORD shader_code_dp2add_sat[] = {
6364 0xffff0200, /* ps_2_0 */
6365 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
6367 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6368 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
6369 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
6371 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
6372 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6373 0x0000ffff /* end */
6375 static const float quad[] =
6377 -1.0f, -1.0f, 0.1f,
6378 -1.0f, 1.0f, 0.1f,
6379 1.0f, -1.0f, 0.1f,
6380 1.0f, 1.0f, 0.1f,
6383 window = create_window();
6384 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6385 ok(!!d3d, "Failed to create a D3D object.\n");
6386 if (!(device = create_device(d3d, window, window, TRUE)))
6388 skip("Failed to create a D3D device, skipping tests.\n");
6389 goto done;
6392 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6393 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6394 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
6396 skip("No ps_2_0 support, skipping tests.\n");
6397 IDirect3DDevice9_Release(device);
6398 goto done;
6401 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
6402 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6404 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
6405 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6407 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
6408 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6410 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6411 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6413 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
6414 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
6415 hr = IDirect3DDevice9_BeginScene(device);
6416 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6417 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
6418 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
6419 hr = IDirect3DDevice9_EndScene(device);
6420 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6422 color = getPixelColor(device, 360, 240);
6423 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1), "Got unexpected color 0x%08x.\n", color);
6425 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6426 ok(SUCCEEDED(hr), "Failed to present frame, hr %#x.\n", hr);
6427 IDirect3DPixelShader9_Release(shader_dp2add);
6429 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
6430 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
6431 hr = IDirect3DDevice9_BeginScene(device);
6432 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6433 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
6434 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
6435 hr = IDirect3DDevice9_EndScene(device);
6436 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6438 color = getPixelColor(device, 360, 240);
6439 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1), "Got unexpected color 0x%08x.\n", color);
6441 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6442 ok(SUCCEEDED(hr), "Failed to present frame, hr %#x.\n", hr);
6443 IDirect3DPixelShader9_Release(shader_dp2add_sat);
6445 refcount = IDirect3DDevice9_Release(device);
6446 ok(!refcount, "Device has %u references left.\n", refcount);
6447 done:
6448 IDirect3D9_Release(d3d);
6449 DestroyWindow(window);
6452 static void cnd_test(void)
6454 IDirect3DPixelShader9 *shader_11_coissue_2, *shader_12_coissue_2, *shader_13_coissue_2, *shader_14_coissue_2;
6455 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
6456 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
6457 IDirect3DDevice9 *device;
6458 IDirect3D9 *d3d;
6459 ULONG refcount;
6460 D3DCAPS9 caps;
6461 HWND window;
6462 DWORD color;
6463 HRESULT hr;
6465 /* ps 1.x shaders are rather picky with writemasks and source swizzles.
6466 * The dp3 is used to copy r0.r to all components of r1, then copy r1.a to
6467 * r0.a. Essentially it does a mov r0.a, r0.r, which isn't allowed as-is
6468 * in 1.x pixel shaders. */
6469 static const DWORD shader_code_11[] =
6471 0xffff0101, /* ps_1_1 */
6472 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6473 0x00000040, 0xb00f0000, /* texcoord t0 */
6474 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
6475 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
6476 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6477 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
6478 0x0000ffff /* end */
6480 static const DWORD shader_code_12[] =
6482 0xffff0102, /* ps_1_2 */
6483 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6484 0x00000040, 0xb00f0000, /* texcoord t0 */
6485 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6486 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
6487 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6488 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
6489 0x0000ffff /* end */
6491 static const DWORD shader_code_13[] =
6493 0xffff0103, /* ps_1_3 */
6494 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6495 0x00000040, 0xb00f0000, /* texcoord t0 */
6496 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6497 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
6498 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6499 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
6500 0x0000ffff /* end */
6502 static const DWORD shader_code_14[] =
6504 0xffff0104, /* ps_1_3 */
6505 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6506 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
6507 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
6508 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
6509 0x0000ffff /* end */
6512 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
6513 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
6514 * set by the compiler, it was added manually after compilation. Note that the COISSUE
6515 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
6516 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
6517 * well enough.
6519 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
6520 * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
6521 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
6522 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
6524 static const DWORD shader_code_11_coissue[] =
6526 0xffff0101, /* ps_1_1 */
6527 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6528 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6529 0x00000040, 0xb00f0000, /* texcoord t0 */
6530 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6531 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6532 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6533 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6534 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6535 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6536 0x0000ffff /* end */
6538 static const DWORD shader_code_11_coissue_2[] =
6540 0xffff0101, /* ps_1_1 */
6541 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6542 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6543 0x00000040, 0xb00f0000, /* texcoord t0 */
6544 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6545 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6546 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6547 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6548 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6549 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6550 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6551 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6552 0x0000ffff /* end */
6554 static const DWORD shader_code_12_coissue[] =
6556 0xffff0102, /* ps_1_2 */
6557 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6558 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6559 0x00000040, 0xb00f0000, /* texcoord t0 */
6560 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6561 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6562 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6563 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6564 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6565 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6566 0x0000ffff /* end */
6568 static const DWORD shader_code_12_coissue_2[] =
6570 0xffff0102, /* ps_1_2 */
6571 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6572 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6573 0x00000040, 0xb00f0000, /* texcoord t0 */
6574 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6575 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6576 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6577 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6578 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6579 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6580 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6581 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6582 0x0000ffff /* end */
6584 static const DWORD shader_code_13_coissue[] =
6586 0xffff0103, /* ps_1_3 */
6587 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6588 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6589 0x00000040, 0xb00f0000, /* texcoord t0 */
6590 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6591 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6592 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6593 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6594 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6595 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6596 0x0000ffff /* end */
6598 static const DWORD shader_code_13_coissue_2[] =
6600 0xffff0103, /* ps_1_3 */
6601 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6602 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6603 0x00000040, 0xb00f0000, /* texcoord t0 */
6604 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6605 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6606 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6607 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6608 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6609 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6610 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6611 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6612 0x0000ffff /* end */
6614 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1]
6615 * texcrd result to cnd, it will compare against 0.5. */
6616 static const DWORD shader_code_14_coissue[] =
6618 0xffff0104, /* ps_1_4 */
6619 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6620 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
6621 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
6622 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0, c1, c2 */
6623 0x0000ffff /* end */
6625 static const DWORD shader_code_14_coissue_2[] =
6627 0xffff0104, /* ps_1_4 */
6628 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6629 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
6630 0x00000001, 0x80080000, 0x80000000, /* mov r0.a, r0.x */
6631 0x00000001, 0x80070001, 0xa0ff0000, /* mov r1.xyz, c0.a */
6632 0x40000050, 0x80080001, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r1.a, r0.a, c1, c2 */
6633 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6634 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
6635 0x0000ffff /* end */
6637 static const float quad1[] =
6639 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6640 -1.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6641 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6642 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6644 static const float quad2[] =
6646 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6647 0.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6648 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6649 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6651 static const float quad3[] =
6653 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6654 0.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6655 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6656 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6658 static const float quad4[] =
6660 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6661 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6662 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6663 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6665 static const float test_data_c1[4] = {0.0f, 0.0f, 0.0f, 0.0f};
6666 static const float test_data_c2[4] = {1.0f, 1.0f, 1.0f, 1.0f};
6667 static const float test_data_c1_coi[4] = {0.0f, 1.0f, 0.0f, 0.0f};
6668 static const float test_data_c2_coi[4] = {1.0f, 0.0f, 1.0f, 1.0f};
6670 window = create_window();
6671 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6672 ok(!!d3d, "Failed to create a D3D object.\n");
6673 if (!(device = create_device(d3d, window, window, TRUE)))
6675 skip("Failed to create a D3D device, skipping tests.\n");
6676 goto done;
6679 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6680 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6681 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
6683 skip("No ps_1_4 support, skipping tests.\n");
6684 IDirect3DDevice9_Release(device);
6685 goto done;
6688 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
6689 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6691 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
6692 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6693 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
6694 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6695 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
6696 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6697 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
6698 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6699 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
6700 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6701 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
6702 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6703 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
6704 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6705 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
6706 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6707 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue_2, &shader_11_coissue_2);
6708 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6709 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue_2, &shader_12_coissue_2);
6710 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6711 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue_2, &shader_13_coissue_2);
6712 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6713 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue_2, &shader_14_coissue_2);
6714 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6716 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
6717 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6718 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
6719 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6720 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6721 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6723 hr = IDirect3DDevice9_BeginScene(device);
6724 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6726 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
6727 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6728 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6729 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6731 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
6732 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6733 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
6734 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6736 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
6737 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6738 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
6739 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6741 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
6742 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6743 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
6744 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6746 hr = IDirect3DDevice9_EndScene(device);
6747 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6749 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6750 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6752 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
6753 color = getPixelColor(device, 158, 118);
6754 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
6755 color = getPixelColor(device, 162, 118);
6756 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
6757 color = getPixelColor(device, 158, 122);
6758 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
6759 color = getPixelColor(device, 162, 122);
6760 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
6762 /* 1.1 shader. All 3 components get set, based on the .w comparison */
6763 color = getPixelColor(device, 158, 358);
6764 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
6765 color = getPixelColor(device, 162, 358);
6766 ok(color_match(color, 0x00000000, 1), "pixel 162, 358 has color 0x%08x, expected 0x00000000.\n", color);
6767 color = getPixelColor(device, 158, 362);
6768 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
6769 color = getPixelColor(device, 162, 362);
6770 ok(color_match(color, 0x00000000, 1), "pixel 162, 362 has color 0x%08x, expected 0x00000000.\n", color);
6772 /* 1.2 shader */
6773 color = getPixelColor(device, 478, 358);
6774 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
6775 color = getPixelColor(device, 482, 358);
6776 ok(color_match(color, 0x00000000, 1), "pixel 482, 358 has color 0x%08x, expected 0x00000000.\n", color);
6777 color = getPixelColor(device, 478, 362);
6778 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
6779 color = getPixelColor(device, 482, 362);
6780 ok(color_match(color, 0x00000000, 1), "pixel 482, 362 has color 0x%08x, expected 0x00000000.\n", color);
6782 /* 1.3 shader */
6783 color = getPixelColor(device, 478, 118);
6784 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
6785 color = getPixelColor(device, 482, 118);
6786 ok(color_match(color, 0x00000000, 1), "pixel 482, 118 has color 0x%08x, expected 0x00000000.\n", color);
6787 color = getPixelColor(device, 478, 122);
6788 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
6789 color = getPixelColor(device, 482, 122);
6790 ok(color_match(color, 0x00000000, 1), "pixel 482, 122 has color 0x%08x, expected 0x00000000.\n", color);
6792 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6793 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6795 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
6796 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6797 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
6798 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6799 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
6800 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6802 hr = IDirect3DDevice9_BeginScene(device);
6803 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6805 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
6806 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6807 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6808 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6810 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
6811 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6812 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
6813 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6815 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
6816 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6817 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
6818 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6820 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
6821 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6822 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
6823 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6825 hr = IDirect3DDevice9_EndScene(device);
6826 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6828 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6829 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6831 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
6832 * that we swapped the values in c1 and c2 to make the other tests return some color
6834 color = getPixelColor(device, 158, 118);
6835 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
6836 color = getPixelColor(device, 162, 118);
6837 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
6838 color = getPixelColor(device, 158, 122);
6839 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
6840 color = getPixelColor(device, 162, 122);
6841 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
6843 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
6844 * (The Win7 nvidia driver always selects c2)
6846 color = getPixelColor(device, 158, 358);
6847 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6848 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
6849 color = getPixelColor(device, 162, 358);
6850 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6851 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
6852 color = getPixelColor(device, 158, 362);
6853 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6854 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
6855 color = getPixelColor(device, 162, 362);
6856 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6857 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
6859 /* 1.2 shader */
6860 color = getPixelColor(device, 478, 358);
6861 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6862 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
6863 color = getPixelColor(device, 482, 358);
6864 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6865 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
6866 color = getPixelColor(device, 478, 362);
6867 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6868 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
6869 color = getPixelColor(device, 482, 362);
6870 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6871 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
6873 /* 1.3 shader */
6874 color = getPixelColor(device, 478, 118);
6875 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6876 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
6877 color = getPixelColor(device, 482, 118);
6878 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6879 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
6880 color = getPixelColor(device, 478, 122);
6881 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6882 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
6883 color = getPixelColor(device, 482, 122);
6884 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6885 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
6887 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6888 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6890 /* Retest with the coissue flag on the alpha instruction instead. This
6891 * works "as expected". The Windows 8 testbot (WARP) seems to handle this
6892 * the same as coissue on .rgb. */
6893 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
6894 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6896 hr = IDirect3DDevice9_BeginScene(device);
6897 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6899 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue_2);
6900 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6901 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6902 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6904 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue_2);
6905 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6906 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
6907 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6909 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue_2);
6910 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6911 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
6912 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6914 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue_2);
6915 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6916 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
6917 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6919 hr = IDirect3DDevice9_EndScene(device);
6920 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6922 /* 1.4 shader */
6923 color = getPixelColor(device, 158, 118);
6924 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
6925 color = getPixelColor(device, 162, 118);
6926 ok(color == 0x00000000, "pixel 162, 118 has color %08x, expected 0x00000000\n", color);
6927 color = getPixelColor(device, 158, 122);
6928 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
6929 color = getPixelColor(device, 162, 122);
6930 ok(color == 0x00000000, "pixel 162, 122 has color %08x, expected 0x00000000\n", color);
6932 /* 1.1 shader */
6933 color = getPixelColor(device, 238, 358);
6934 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6935 "pixel 238, 358 has color %08x, expected 0x00ffffff\n", color);
6936 color = getPixelColor(device, 242, 358);
6937 ok(color_match(color, 0x00000000, 1),
6938 "pixel 242, 358 has color %08x, expected 0x00000000\n", color);
6939 color = getPixelColor(device, 238, 362);
6940 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6941 "pixel 238, 362 has color %08x, expected 0x00ffffff\n", color);
6942 color = getPixelColor(device, 242, 362);
6943 ok(color_match(color, 0x00000000, 1),
6944 "pixel 242, 362 has color %08x, expected 0x00000000\n", color);
6946 /* 1.2 shader */
6947 color = getPixelColor(device, 558, 358);
6948 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6949 "pixel 558, 358 has color %08x, expected 0x00ffffff\n", color);
6950 color = getPixelColor(device, 562, 358);
6951 ok(color_match(color, 0x00000000, 1),
6952 "pixel 562, 358 has color %08x, expected 0x00000000\n", color);
6953 color = getPixelColor(device, 558, 362);
6954 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6955 "pixel 558, 362 has color %08x, expected 0x00ffffff\n", color);
6956 color = getPixelColor(device, 562, 362);
6957 ok(color_match(color, 0x00000000, 1),
6958 "pixel 562, 362 has color %08x, expected 0x00000000\n", color);
6960 /* 1.3 shader */
6961 color = getPixelColor(device, 558, 118);
6962 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6963 "pixel 558, 118 has color %08x, expected 0x00ffffff\n", color);
6964 color = getPixelColor(device, 562, 118);
6965 ok(color_match(color, 0x00000000, 1),
6966 "pixel 562, 118 has color %08x, expected 0x00000000\n", color);
6967 color = getPixelColor(device, 558, 122);
6968 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6969 "pixel 558, 122 has color %08x, expected 0x00ffffff\n", color);
6970 color = getPixelColor(device, 562, 122);
6971 ok(color_match(color, 0x00000000, 1),
6972 "pixel 562, 122 has color %08x, expected 0x00000000\n", color);
6974 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6975 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6977 IDirect3DPixelShader9_Release(shader_14_coissue_2);
6978 IDirect3DPixelShader9_Release(shader_13_coissue_2);
6979 IDirect3DPixelShader9_Release(shader_12_coissue_2);
6980 IDirect3DPixelShader9_Release(shader_11_coissue_2);
6981 IDirect3DPixelShader9_Release(shader_14_coissue);
6982 IDirect3DPixelShader9_Release(shader_13_coissue);
6983 IDirect3DPixelShader9_Release(shader_12_coissue);
6984 IDirect3DPixelShader9_Release(shader_11_coissue);
6985 IDirect3DPixelShader9_Release(shader_14);
6986 IDirect3DPixelShader9_Release(shader_13);
6987 IDirect3DPixelShader9_Release(shader_12);
6988 IDirect3DPixelShader9_Release(shader_11);
6989 refcount = IDirect3DDevice9_Release(device);
6990 ok(!refcount, "Device has %u references left.\n", refcount);
6991 done:
6992 IDirect3D9_Release(d3d);
6993 DestroyWindow(window);
6996 static void nested_loop_test(void)
6998 IDirect3DVertexShader9 *vshader;
6999 IDirect3DPixelShader9 *shader;
7000 IDirect3DDevice9 *device;
7001 IDirect3D9 *d3d;
7002 ULONG refcount;
7003 D3DCAPS9 caps;
7004 DWORD color;
7005 HWND window;
7006 HRESULT hr;
7008 static const DWORD shader_code[] =
7010 0xffff0300, /* ps_3_0 */
7011 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
7012 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
7013 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
7014 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7015 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
7016 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
7017 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
7018 0x0000001d, /* endloop */
7019 0x0000001d, /* endloop */
7020 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7021 0x0000ffff /* end */
7023 static const DWORD vshader_code[] =
7025 0xfffe0300, /* vs_3_0 */
7026 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7027 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7028 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7029 0x0000ffff /* end */
7031 static const float quad[] =
7033 -1.0f, -1.0f, 0.1f,
7034 -1.0f, 1.0f, 0.1f,
7035 1.0f, -1.0f, 0.1f,
7036 1.0f, 1.0f, 0.1f,
7039 window = create_window();
7040 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7041 ok(!!d3d, "Failed to create a D3D object.\n");
7042 if (!(device = create_device(d3d, window, window, TRUE)))
7044 skip("Failed to create a D3D device, skipping tests.\n");
7045 goto done;
7048 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7049 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7050 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
7052 skip("No shader model 3 support, skipping tests.\n");
7053 IDirect3DDevice9_Release(device);
7054 goto done;
7057 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7058 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
7059 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7060 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
7061 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
7062 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
7063 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
7064 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
7065 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7066 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
7067 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 1.0f, 0);
7068 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7070 hr = IDirect3DDevice9_BeginScene(device);
7071 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7072 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
7073 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7074 hr = IDirect3DDevice9_EndScene(device);
7075 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7077 color = getPixelColor(device, 360, 240);
7078 ok(color_match(color, 0x00800000, 1),
7079 "Nested loop test returned color 0x%08x, expected 0x00800000.\n", color);
7081 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7082 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7084 IDirect3DPixelShader9_Release(shader);
7085 IDirect3DVertexShader9_Release(vshader);
7086 refcount = IDirect3DDevice9_Release(device);
7087 ok(!refcount, "Device has %u references left.\n", refcount);
7088 done:
7089 IDirect3D9_Release(d3d);
7090 DestroyWindow(window);
7093 static void pretransformed_varying_test(void)
7095 /* dcl_position: fails to compile */
7096 static const DWORD blendweight_code[] =
7098 0xffff0300, /* ps_3_0 */
7099 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
7100 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7101 0x0000ffff /* end */
7103 static const DWORD blendindices_code[] =
7105 0xffff0300, /* ps_3_0 */
7106 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
7107 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7108 0x0000ffff /* end */
7110 static const DWORD normal_code[] =
7112 0xffff0300, /* ps_3_0 */
7113 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
7114 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7115 0x0000ffff /* end */
7117 /* psize: fails? */
7118 static const DWORD texcoord0_code[] =
7120 0xffff0300, /* ps_3_0 */
7121 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
7122 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7123 0x0000ffff /* end */
7125 static const DWORD tangent_code[] =
7127 0xffff0300, /* ps_3_0 */
7128 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
7129 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7130 0x0000ffff /* end */
7132 static const DWORD binormal_code[] =
7134 0xffff0300, /* ps_3_0 */
7135 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
7136 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7137 0x0000ffff /* end */
7139 /* tessfactor: fails */
7140 /* positiont: fails */
7141 static const DWORD color_code[] =
7143 0xffff0300, /* ps_3_0 */
7144 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
7145 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7146 0x0000ffff /* end */
7148 static const DWORD fog_code[] =
7150 0xffff0300, /* ps_3_0 */
7151 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
7152 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7153 0x0000ffff /* end */
7155 static const DWORD depth_code[] =
7157 0xffff0300, /* ps_3_0 */
7158 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
7159 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7160 0x0000ffff /* end */
7162 static const DWORD specular_code[] =
7164 0xffff0300, /* ps_3_0 */
7165 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
7166 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7167 0x0000ffff /* end */
7169 /* sample: fails */
7170 static const DWORD texcoord1_code[] =
7172 0xffff0300, /* ps_3_0 */
7173 0x0200001f, 0x80010005, 0x900f0000, /* dcl_texcoord1, v0 */
7174 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7175 0x0000ffff /* end */
7177 static const DWORD texcoord1_alpha_code[] =
7179 0xffff0300, /* ps_3_0 */
7180 0x0200001f, 0x80010005, 0x900f0000, /* dcl_texcoord1, v0 */
7181 0x02000001, 0x800f0800, 0x90ff0000, /* mov oC0, v0.w */
7182 0x0000ffff /* end */
7185 static const struct
7187 const char *name;
7188 const DWORD *shader_code;
7189 DWORD color;
7190 BOOL todo;
7191 BOOL broken_warp;
7193 tests[] =
7195 {"blendweight", blendweight_code, 0x00191919, TRUE },
7196 {"blendindices", blendindices_code, 0x00333333, TRUE },
7197 {"normal", normal_code, 0x004c4c4c, TRUE },
7198 {"texcoord0", texcoord0_code, 0x00808c8c, FALSE},
7199 {"tangent", tangent_code, 0x00999999, TRUE },
7200 {"binormal", binormal_code, 0x00b2b2b2, TRUE },
7201 {"color", color_code, 0x00e6e6e6, FALSE},
7202 {"fog", fog_code, 0x00666666, TRUE },
7203 {"depth", depth_code, 0x00cccccc, TRUE },
7204 {"specular", specular_code, 0x004488ff, FALSE},
7205 {"texcoord1", texcoord1_code, 0x00000000, FALSE},
7206 {"texcoord1 alpha", texcoord1_alpha_code, 0x00000000, FALSE, TRUE},
7208 /* Declare a monster vertex type :-) */
7209 static const D3DVERTEXELEMENT9 decl_elements[] = {
7210 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
7211 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
7212 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
7213 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
7214 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
7215 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7216 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
7217 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
7218 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
7219 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7220 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
7221 D3DDECL_END()
7224 static const struct
7226 float pos_x, pos_y, pos_z, rhw;
7227 float weight_1, weight_2, weight_3, weight_4;
7228 float index_1, index_2, index_3, index_4;
7229 float normal_1, normal_2, normal_3, normal_4;
7230 float fog_1, fog_2, fog_3, fog_4;
7231 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
7232 float tangent_1, tangent_2, tangent_3, tangent_4;
7233 float binormal_1, binormal_2, binormal_3, binormal_4;
7234 float depth_1, depth_2, depth_3, depth_4;
7235 D3DCOLOR diffuse;
7236 D3DCOLOR specular;
7238 data[] =
7241 0.0f, 0.0f, 0.1f, 1.0f,
7242 0.1f, 0.1f, 0.1f, 0.1f,
7243 0.2f, 0.2f, 0.2f, 0.2f,
7244 0.3f, 0.3f, 0.3f, 0.3f,
7245 0.4f, 0.4f, 0.4f, 0.4f,
7246 0.5f, 0.55f, 0.55f, 0.55f,
7247 0.6f, 0.6f, 0.6f, 0.7f,
7248 0.7f, 0.7f, 0.7f, 0.6f,
7249 0.8f, 0.8f, 0.8f, 0.8f,
7250 0xe6e6e6e6, /* 0.9 * 256 */
7251 0x224488ff, /* Nothing special */
7254 640.0f, 0.0f, 0.1f, 1.0f,
7255 0.1f, 0.1f, 0.1f, 0.1f,
7256 0.2f, 0.2f, 0.2f, 0.2f,
7257 0.3f, 0.3f, 0.3f, 0.3f,
7258 0.4f, 0.4f, 0.4f, 0.4f,
7259 0.5f, 0.55f, 0.55f, 0.55f,
7260 0.6f, 0.6f, 0.6f, 0.7f,
7261 0.7f, 0.7f, 0.7f, 0.6f,
7262 0.8f, 0.8f, 0.8f, 0.8f,
7263 0xe6e6e6e6, /* 0.9 * 256 */
7264 0x224488ff, /* Nothing special */
7267 0.0f, 480.0f, 0.1f, 1.0f,
7268 0.1f, 0.1f, 0.1f, 0.1f,
7269 0.2f, 0.2f, 0.2f, 0.2f,
7270 0.3f, 0.3f, 0.3f, 0.3f,
7271 0.4f, 0.4f, 0.4f, 0.4f,
7272 0.5f, 0.55f, 0.55f, 0.55f,
7273 0.6f, 0.6f, 0.6f, 0.7f,
7274 0.7f, 0.7f, 0.7f, 0.6f,
7275 0.8f, 0.8f, 0.8f, 0.8f,
7276 0xe6e6e6e6, /* 0.9 * 256 */
7277 0x224488ff, /* Nothing special */
7280 640.0f, 480.0f, 0.1f, 1.0f,
7281 0.1f, 0.1f, 0.1f, 0.1f,
7282 0.2f, 0.2f, 0.2f, 0.2f,
7283 0.3f, 0.3f, 0.3f, 0.3f,
7284 0.4f, 0.4f, 0.4f, 0.4f,
7285 0.5f, 0.55f, 0.55f, 0.55f,
7286 0.6f, 0.6f, 0.6f, 0.7f,
7287 0.7f, 0.7f, 0.7f, 0.6f,
7288 0.8f, 0.8f, 0.8f, 0.8f,
7289 0xe6e6e6e6, /* 0.9 * 256 */
7290 0x224488ff, /* Nothing special */
7293 D3DADAPTER_IDENTIFIER9 identifier;
7294 IDirect3DVertexDeclaration9 *decl;
7295 IDirect3DDevice9 *device;
7296 IDirect3D9 *d3d;
7297 unsigned int i;
7298 ULONG refcount;
7299 D3DCAPS9 caps;
7300 DWORD color;
7301 HWND window;
7302 HRESULT hr;
7303 BOOL warp;
7305 window = create_window();
7306 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7307 ok(!!d3d, "Failed to create a D3D object.\n");
7308 if (!(device = create_device(d3d, window, window, TRUE)))
7310 skip("Failed to create a D3D device, skipping tests.\n");
7311 goto done;
7314 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7315 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7316 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
7318 skip("No shader model 3 support, skipping tests.\n");
7319 IDirect3DDevice9_Release(device);
7320 goto done;
7323 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
7324 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
7325 warp = adapter_is_warp(&identifier);
7327 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
7328 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7329 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
7330 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
7332 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
7334 IDirect3DPixelShader9 *shader;
7336 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
7337 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7339 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &shader);
7340 ok(SUCCEEDED(hr), "Failed to create pixel shader for test %s, hr %#x.\n", tests[i].name, hr);
7342 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7343 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7345 hr = IDirect3DDevice9_BeginScene(device);
7346 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7347 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(*data));
7348 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7349 hr = IDirect3DDevice9_EndScene(device);
7350 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7352 /* This isn't a weekend's job to fix, ignore the problem for now.
7353 * Needs a replacement pipeline. */
7354 color = getPixelColor(device, 360, 240);
7355 if (tests[i].todo)
7356 todo_wine ok(color_match(color, tests[i].color, 1)
7357 || broken(color_match(color, 0x00000000, 1)
7358 && tests[i].shader_code == blendindices_code),
7359 "Test %s returned color 0x%08x, expected 0x%08x (todo).\n",
7360 tests[i].name, color, tests[i].color);
7361 else
7362 ok(color_match(color, tests[i].color, 1) || broken(warp && tests[i].broken_warp),
7363 "Test %s returned color 0x%08x, expected 0x%08x.\n",
7364 tests[i].name, color, tests[i].color);
7366 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7367 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7369 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7370 ok(SUCCEEDED(hr), "Failed to set pixel shader for test %s, hr %#x.\n", tests[i].name, hr);
7371 IDirect3DPixelShader9_Release(shader);
7374 IDirect3DVertexDeclaration9_Release(decl);
7375 refcount = IDirect3DDevice9_Release(device);
7376 ok(!refcount, "Device has %u references left.\n", refcount);
7377 done:
7378 IDirect3D9_Release(d3d);
7379 DestroyWindow(window);
7382 static void test_compare_instructions(void)
7384 IDirect3DVertexShader9 *shader_slt_scalar;
7385 IDirect3DVertexShader9 *shader_sge_scalar;
7386 IDirect3DVertexShader9 *shader_slt_vec;
7387 IDirect3DVertexShader9 *shader_sge_vec;
7388 IDirect3DDevice9 *device;
7389 IDirect3D9 *d3d;
7390 D3DCOLOR color;
7391 ULONG refcount;
7392 D3DCAPS9 caps;
7393 HWND window;
7394 HRESULT hr;
7396 static const DWORD shader_sge_vec_code[] =
7398 0xfffe0101, /* vs_1_1 */
7399 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7400 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7401 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7402 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
7403 0x0000ffff /* end */
7405 static const DWORD shader_slt_vec_code[] =
7407 0xfffe0101, /* vs_1_1 */
7408 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7409 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7410 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7411 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
7412 0x0000ffff /* end */
7414 static const DWORD shader_sge_scalar_code[] =
7416 0xfffe0101, /* vs_1_1 */
7417 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7418 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7419 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7420 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
7421 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
7422 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
7423 0x0000ffff /* end */
7425 static const DWORD shader_slt_scalar_code[] =
7427 0xfffe0101, /* vs_1_1 */
7428 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7429 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7430 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7431 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
7432 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
7433 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
7434 0x0000ffff /* end */
7436 static const float quad1[] =
7438 -1.0f, -1.0f, 0.1f,
7439 -1.0f, 0.0f, 0.1f,
7440 0.0f, -1.0f, 0.1f,
7441 0.0f, 0.0f, 0.1f,
7443 static const float quad2[] =
7445 0.0f, -1.0f, 0.1f,
7446 0.0f, 0.0f, 0.1f,
7447 1.0f, -1.0f, 0.1f,
7448 1.0f, 0.0f, 0.1f,
7450 static const float quad3[] =
7452 -1.0f, 0.0f, 0.1f,
7453 -1.0f, 1.0f, 0.1f,
7454 0.0f, 0.0f, 0.1f,
7455 0.0f, 1.0f, 0.1f,
7457 static const float quad4[] =
7459 0.0f, 0.0f, 0.1f,
7460 0.0f, 1.0f, 0.1f,
7461 1.0f, 0.0f, 0.1f,
7462 1.0f, 1.0f, 0.1f,
7464 static const float const0[4] = {0.8f, 0.2f, 0.2f, 0.2f};
7465 static const float const1[4] = {0.2f, 0.8f, 0.2f, 0.2f};
7467 window = create_window();
7468 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7469 ok(!!d3d, "Failed to create a D3D object.\n");
7470 if (!(device = create_device(d3d, window, window, TRUE)))
7472 skip("Failed to create a D3D device, skipping tests.\n");
7473 goto done;
7476 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7477 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7478 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
7480 skip("No vs_1_1 support, skipping tests.\n");
7481 IDirect3DDevice9_Release(device);
7482 goto done;
7485 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
7486 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
7488 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
7489 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7490 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
7491 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7492 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
7493 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7494 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
7495 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7496 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
7497 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
7498 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
7499 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
7500 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7501 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
7503 hr = IDirect3DDevice9_BeginScene(device);
7504 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7506 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
7507 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7508 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
7509 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7511 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
7512 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7513 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
7514 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7516 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
7517 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7518 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
7519 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7521 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
7522 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
7524 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
7525 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7526 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
7527 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7529 hr = IDirect3DDevice9_EndScene(device);
7530 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7532 color = getPixelColor(device, 160, 360);
7533 ok(color == 0x00ff00ff, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00ff00ff\n", color);
7534 color = getPixelColor(device, 480, 360);
7535 ok(color == 0x0000ff00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000ff00\n", color);
7536 color = getPixelColor(device, 160, 120);
7537 ok(color == 0x00ffffff, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00ffffff\n", color);
7538 color = getPixelColor(device, 480, 160);
7539 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
7541 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7542 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7544 IDirect3DVertexShader9_Release(shader_sge_vec);
7545 IDirect3DVertexShader9_Release(shader_slt_vec);
7546 IDirect3DVertexShader9_Release(shader_sge_scalar);
7547 IDirect3DVertexShader9_Release(shader_slt_scalar);
7548 refcount = IDirect3DDevice9_Release(device);
7549 ok(!refcount, "Device has %u references left.\n", refcount);
7550 done:
7551 IDirect3D9_Release(d3d);
7552 DestroyWindow(window);
7555 static void test_vshader_input(void)
7557 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
7558 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
7559 IDirect3DVertexDeclaration9 *decl_nocolor;
7560 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
7561 D3DADAPTER_IDENTIFIER9 identifier;
7562 IDirect3DPixelShader9 *ps;
7563 IDirect3DDevice9 *device;
7564 IDirect3D9 *d3d;
7565 ULONG refcount;
7566 unsigned int i;
7567 D3DCAPS9 caps;
7568 DWORD color;
7569 HWND window;
7570 HRESULT hr;
7571 BOOL warp;
7573 static const DWORD swapped_shader_code_3[] =
7575 0xfffe0300, /* vs_3_0 */
7576 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7577 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7578 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7579 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7580 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7581 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7582 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7583 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7584 0x0000ffff /* end */
7586 static const DWORD swapped_shader_code_1[] =
7588 0xfffe0101, /* vs_1_1 */
7589 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7590 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7591 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7592 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
7593 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7594 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7595 0x0000ffff /* end */
7597 static const DWORD swapped_shader_code_2[] =
7599 0xfffe0200, /* vs_2_0 */
7600 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7601 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7602 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7603 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
7604 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7605 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7606 0x0000ffff /* end */
7608 static const DWORD texcoord_color_shader_code_3[] =
7610 0xfffe0300, /* vs_3_0 */
7611 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7612 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7613 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7614 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7615 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7616 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
7617 0x0000ffff /* end */
7619 static const DWORD texcoord_color_shader_code_2[] =
7621 0xfffe0200, /* vs_2_0 */
7622 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7623 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7624 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7625 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
7626 0x0000ffff /* end */
7628 static const DWORD texcoord_color_shader_code_1[] =
7630 0xfffe0101, /* vs_1_1 */
7631 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7632 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7633 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7634 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
7635 0x0000ffff /* end */
7637 static const DWORD color_color_shader_code_3[] =
7639 0xfffe0300, /* vs_3_0 */
7640 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7641 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7642 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7643 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7644 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7645 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
7646 0x0000ffff /* end */
7648 static const DWORD color_color_shader_code_2[] =
7650 0xfffe0200, /* vs_2_0 */
7651 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7652 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7653 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7654 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
7655 0x0000ffff /* end */
7657 static const DWORD color_color_shader_code_1[] =
7659 0xfffe0101, /* vs_1_1 */
7660 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7661 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7662 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7663 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
7664 0x0000ffff /* end */
7666 static const DWORD ps3_code[] =
7668 0xffff0300, /* ps_3_0 */
7669 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
7670 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7671 0x0000ffff /* end */
7673 static const float quad1[] =
7675 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7676 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7677 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7678 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7680 static const float quad2[] =
7682 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7683 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7684 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7685 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7687 static const float quad3[] =
7689 -1.0f, 0.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f,
7690 -1.0f, 1.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
7691 0.0f, 0.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
7692 0.0f, 1.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
7694 static const float quad4[] =
7696 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7697 0.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7698 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7699 1.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7701 static const float quad1_modified[] =
7703 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
7704 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f,
7705 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
7706 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, -1.0f, -1.0f, 0.0f,
7708 static const float quad2_modified[] =
7710 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7711 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7712 1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7713 1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7715 static const struct
7717 struct vec3 position;
7718 DWORD diffuse;
7720 quad1_color[] =
7722 {{-1.0f, -1.0f, 0.1f}, 0x00ff8040},
7723 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
7724 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7725 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7727 quad2_color[] =
7729 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7730 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7731 {{ 1.0f, -1.0f, 0.1f}, 0x00ff8040},
7732 {{ 1.0f, 0.0f, 0.1f}, 0x00ff8040},
7734 quad3_color[] =
7736 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
7737 {{-1.0f, 1.0f, 0.1f}, 0x00ff8040},
7738 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7739 {{ 0.0f, 1.0f, 0.1f}, 0x00ff8040},
7741 static const float quad4_color[] =
7743 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7744 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7745 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7746 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7748 static const struct vec3 quad_nocolor[] =
7750 {-1.0f, -1.0f, 0.1f},
7751 {-1.0f, 1.0f, 0.1f},
7752 { 1.0f, -1.0f, 0.1f},
7753 { 1.0f, 1.0f, 0.1f},
7755 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] =
7757 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7758 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7759 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7760 D3DDECL_END()
7762 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] =
7764 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7765 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7766 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7767 D3DDECL_END()
7769 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] =
7771 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7772 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7773 D3DDECL_END()
7775 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] =
7777 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7778 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7779 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
7780 D3DDECL_END()
7782 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] =
7784 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7785 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7786 D3DDECL_END()
7788 static const D3DVERTEXELEMENT9 decl_elements_color_color[] =
7790 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7791 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7792 D3DDECL_END()
7794 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] =
7796 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7797 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7798 D3DDECL_END()
7800 static const D3DVERTEXELEMENT9 decl_elements_color_float[] =
7802 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7803 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7804 D3DDECL_END()
7806 static const D3DVERTEXELEMENT9 decl_elements_nocolor[] =
7808 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7809 D3DDECL_END()
7811 static const float normalize[4] = {1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f};
7812 static const float no_normalize[4] = {1.0f, 1.0f, 1.0f, 1.0f};
7814 window = create_window();
7815 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7816 ok(!!d3d, "Failed to create a D3D object.\n");
7817 if (!(device = create_device(d3d, window, window, TRUE)))
7819 skip("Failed to create a D3D device, skipping tests.\n");
7820 goto done;
7823 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7824 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7825 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
7827 skip("No vs_3_0 support, skipping tests.\n");
7828 IDirect3DDevice9_Release(device);
7829 goto done;
7831 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
7833 skip("No ps_3_0 support, skipping tests.\n");
7834 IDirect3DDevice9_Release(device);
7835 goto done;
7838 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
7839 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
7840 warp = adapter_is_warp(&identifier);
7842 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
7843 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7844 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
7845 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7846 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
7847 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7848 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
7849 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7851 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
7852 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7853 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
7854 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7855 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
7856 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7857 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
7858 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7859 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_nocolor, &decl_nocolor);
7860 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7862 hr = IDirect3DDevice9_CreatePixelShader(device, ps3_code, &ps);
7863 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
7865 for (i = 1; i <= 3; ++i)
7867 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
7868 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
7869 if(i == 3) {
7870 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
7871 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7872 hr = IDirect3DDevice9_SetPixelShader(device, ps);
7873 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7874 } else if(i == 2){
7875 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
7876 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7877 } else if(i == 1) {
7878 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
7879 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7882 hr = IDirect3DDevice9_BeginScene(device);
7883 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7885 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
7886 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7888 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
7889 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7890 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
7891 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7893 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
7894 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7895 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
7896 if (i == 3 || i == 2)
7897 ok(SUCCEEDED(hr), "Failed to draw, i %u, hr %#x.\n", i, hr);
7898 else if (i == 1)
7899 /* Succeeds or fails, depending on SW or HW vertex processing. */
7900 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
7902 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
7903 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7904 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
7905 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7907 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
7908 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7909 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
7910 if (i == 3 || i == 2)
7911 ok(SUCCEEDED(hr), "Failed to draw, i %u, hr %#x.\n", i, hr);
7912 else if (i == 1)
7913 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
7915 hr = IDirect3DDevice9_EndScene(device);
7916 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7918 if(i == 3 || i == 2) {
7919 color = getPixelColor(device, 160, 360);
7920 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
7921 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00ffff80\n", color);
7923 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
7924 color = getPixelColor(device, 480, 360);
7925 /* On the Windows 8 testbot (WARP) the draw succeeds, but uses
7926 * mostly random data as input. */
7927 ok(color == 0x00ffff00 || color == 0x00ff0000 || broken(warp),
7928 "Got unexpected color 0x%08x for quad 2 (1crd).\n", color);
7929 color = getPixelColor(device, 160, 120);
7930 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
7931 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
7932 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00ff0080\n", color);
7934 color = getPixelColor(device, 480, 160);
7935 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
7936 } else if(i == 1) {
7937 color = getPixelColor(device, 160, 360);
7938 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
7939 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00ffff80\n", color);
7940 color = getPixelColor(device, 480, 360);
7941 /* Accept the clear color as well in this case, since SW VP
7942 * returns an error. On the Windows 8 testbot (WARP) the draw
7943 * succeeds, but uses mostly random data as input. */
7944 ok(color == 0x00ffff00 || color == 0x00ff0000 || broken(warp),
7945 "Got unexpected color 0x%08x for quad 2 (1crd).\n", color);
7946 color = getPixelColor(device, 160, 120);
7947 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
7948 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00ff0080\n", color);
7949 color = getPixelColor(device, 480, 160);
7950 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
7953 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7954 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7956 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
7957 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7959 /* Now find out if the whole streams are re-read, or just the last
7960 * active value for the vertices is used. */
7961 hr = IDirect3DDevice9_BeginScene(device);
7962 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7964 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
7965 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7967 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
7968 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7969 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
7970 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7972 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
7973 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7974 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
7975 if (i == 3 || i == 2)
7976 ok(SUCCEEDED(hr), "Failed to draw, i %u, hr %#x.\n", i, hr);
7977 else if (i == 1)
7978 /* Succeeds or fails, depending on SW or HW vertex processing. */
7979 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
7981 hr = IDirect3DDevice9_EndScene(device);
7982 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7984 color = getPixelColor(device, 480, 350);
7985 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
7986 * as well.
7988 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
7989 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
7990 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
7991 * refrast's result.
7993 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
7995 ok(color == 0x000000ff || color == 0x00808080 || color == 0x00000000
7996 || broken(color_match(color, D3DCOLOR_ARGB(0x00, 0x0b, 0x75, 0x80), 1)),
7997 "Got unexpected color 0x%08x for quad 2 (different colors).\n", color);
7999 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8000 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8002 IDirect3DDevice9_SetVertexShader(device, NULL);
8003 IDirect3DDevice9_SetPixelShader(device, NULL);
8004 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8006 IDirect3DVertexShader9_Release(swapped_shader);
8009 for (i = 1; i <= 3; ++i)
8011 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
8012 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
8013 if(i == 3) {
8014 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
8015 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8016 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
8017 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8018 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8019 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
8020 } else if(i == 2){
8021 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
8022 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8023 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
8024 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8025 } else if(i == 1) {
8026 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
8027 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8028 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
8029 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8032 hr = IDirect3DDevice9_BeginScene(device);
8033 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8035 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
8036 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8037 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
8038 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8039 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
8040 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8042 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
8043 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8045 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
8046 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
8047 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
8048 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8049 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
8050 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8052 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
8053 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
8054 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
8055 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8056 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
8057 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8059 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
8060 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8061 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
8062 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8064 hr = IDirect3DDevice9_EndScene(device);
8065 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8067 color = getPixelColor(device, 160, 360);
8068 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
8069 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
8070 color = getPixelColor(device, 480, 360);
8071 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
8072 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
8073 color = getPixelColor(device, 160, 120);
8074 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
8075 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
8076 color = getPixelColor(device, 480, 160);
8077 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
8078 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00ffff00\n", color);
8080 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8081 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8083 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_nocolor);
8084 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8086 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
8087 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8089 hr = IDirect3DDevice9_BeginScene(device);
8090 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8091 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_nocolor, sizeof(quad_nocolor[0]));
8092 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8093 hr = IDirect3DDevice9_EndScene(device);
8094 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8096 /* WARP ends up using the color attribute from the previous draw. Let's mark
8097 * that behavior as broken. */
8098 color = getPixelColor(device, 160, 360);
8099 ok(color_match(color, 0x00000000, 1)
8100 || broken(color_match(color, 0x00ffff00, 1)),
8101 "Got unexpected color 0x%08x for no color attribute test.\n", color);
8103 IDirect3DDevice9_SetVertexShader(device, NULL);
8104 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8105 IDirect3DDevice9_SetPixelShader(device, NULL);
8107 IDirect3DVertexShader9_Release(texcoord_color_shader);
8108 IDirect3DVertexShader9_Release(color_color_shader);
8111 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
8112 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
8113 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
8114 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
8116 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
8117 IDirect3DVertexDeclaration9_Release(decl_color_color);
8118 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
8119 IDirect3DVertexDeclaration9_Release(decl_color_float);
8120 IDirect3DVertexDeclaration9_Release(decl_nocolor);
8122 IDirect3DPixelShader9_Release(ps);
8123 refcount = IDirect3DDevice9_Release(device);
8124 ok(!refcount, "Device has %u references left.\n", refcount);
8125 done:
8126 IDirect3D9_Release(d3d);
8127 DestroyWindow(window);
8130 static void srgbtexture_test(void)
8132 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
8133 * texture stage state to render a quad using that texture. The resulting
8134 * color components should be 0x36 (~ 0.21), per this formula:
8135 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
8136 * This is true where srgb_color > 0.04045. */
8137 struct IDirect3DTexture9 *texture;
8138 struct IDirect3DSurface9 *surface;
8139 IDirect3DDevice9 *device;
8140 IDirect3D9 *d3d;
8141 D3DCOLOR color;
8142 ULONG refcount;
8143 HWND window;
8144 HRESULT hr;
8146 static const float quad[] =
8148 -1.0f, -1.0f, 0.0f, 0.0f, 1.0f,
8149 -1.0f, 1.0f, 0.0f, 0.0f, 0.0f,
8150 1.0f, -1.0f, 0.0f, 1.0f, 1.0f,
8151 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
8154 window = create_window();
8155 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8156 ok(!!d3d, "Failed to create a D3D object.\n");
8157 if (!(device = create_device(d3d, window, window, TRUE)))
8159 skip("Failed to create a D3D device, skipping tests.\n");
8160 goto done;
8163 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
8164 D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK)
8166 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported.\n");
8167 IDirect3DDevice9_Release(device);
8168 goto done;
8171 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
8172 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
8173 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8174 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
8176 fill_surface(surface, 0xff7f7f7f, 0);
8177 IDirect3DSurface9_Release(surface);
8179 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8180 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8181 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8182 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
8184 hr = IDirect3DDevice9_BeginScene(device);
8185 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8187 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
8188 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
8189 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8190 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8191 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
8192 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8194 hr = IDirect3DDevice9_EndScene(device);
8195 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8197 color = getPixelColor(device, 320, 240);
8198 ok(color_match(color, 0x00363636, 1), "sRGB quad has color 0x%08x, expected 0x00363636.\n", color);
8200 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8201 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8203 IDirect3DTexture9_Release(texture);
8204 refcount = IDirect3DDevice9_Release(device);
8205 ok(!refcount, "Device has %u references left.\n", refcount);
8206 done:
8207 IDirect3D9_Release(d3d);
8208 DestroyWindow(window);
8211 static void test_shademode(void)
8213 IDirect3DVertexBuffer9 *vb_strip;
8214 IDirect3DVertexBuffer9 *vb_list;
8215 IDirect3DVertexShader9 *vs;
8216 IDirect3DPixelShader9 *ps;
8217 IDirect3DDevice9 *device;
8218 DWORD color0, color1;
8219 void *data = NULL;
8220 IDirect3D9 *d3d;
8221 ULONG refcount;
8222 D3DCAPS9 caps;
8223 HWND window;
8224 HRESULT hr;
8225 UINT i;
8226 static const DWORD vs1_code[] =
8228 0xfffe0101, /* vs_1_1 */
8229 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8230 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
8231 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8232 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
8233 0x0000ffff
8235 static const DWORD vs2_code[] =
8237 0xfffe0200, /* vs_2_0 */
8238 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8239 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
8240 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8241 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
8242 0x0000ffff
8244 static const DWORD vs3_code[] =
8246 0xfffe0300, /* vs_3_0 */
8247 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8248 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
8249 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8250 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
8251 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8252 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
8253 0x0000ffff
8255 static const DWORD ps1_code[] =
8257 0xffff0101, /* ps_1_1 */
8258 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
8259 0x0000ffff
8261 static const DWORD ps2_code[] =
8263 0xffff0200, /* ps_2_0 */
8264 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
8265 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8266 0x0000ffff
8268 static const DWORD ps3_code[] =
8270 0xffff0300, /* ps_3_0 */
8271 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
8272 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8273 0x0000ffff
8275 static const struct
8277 struct vec3 position;
8278 DWORD diffuse;
8280 quad_strip[] =
8282 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
8283 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8284 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8285 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
8287 quad_list[] =
8289 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
8290 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8291 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8293 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8294 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8295 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
8297 static const struct test_shader
8299 DWORD version;
8300 const DWORD *code;
8302 novs = {0, NULL},
8303 vs_1 = {D3DVS_VERSION(1, 1), vs1_code},
8304 vs_2 = {D3DVS_VERSION(2, 0), vs2_code},
8305 vs_3 = {D3DVS_VERSION(3, 0), vs3_code},
8306 nops = {0, NULL},
8307 ps_1 = {D3DPS_VERSION(1, 1), ps1_code},
8308 ps_2 = {D3DPS_VERSION(2, 0), ps2_code},
8309 ps_3 = {D3DPS_VERSION(3, 0), ps3_code};
8310 static const struct
8312 const struct test_shader *vs, *ps;
8313 DWORD primtype;
8314 DWORD shademode;
8315 DWORD color0, color1;
8316 BOOL todo;
8318 tests[] =
8320 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8321 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_PHONG, 0x000dca28, 0x000d45c7, FALSE},
8322 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8323 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_PHONG, 0x000dca28, 0x000d45c7, FALSE},
8324 {&novs, &nops, D3DPT_TRIANGLELIST, D3DSHADE_FLAT, 0x00ff0000, 0x000000ff, FALSE},
8325 {&novs, &nops, D3DPT_TRIANGLELIST, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8326 {&vs_1, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8327 {&vs_1, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8328 {&vs_1, &ps_1, D3DPT_TRIANGLELIST, D3DSHADE_FLAT, 0x00ff0000, 0x000000ff, FALSE},
8329 {&vs_1, &ps_1, D3DPT_TRIANGLELIST, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8330 {&novs, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8331 {&vs_1, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8332 {&vs_2, &ps_2, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8333 {&vs_2, &ps_2, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8334 {&vs_3, &ps_3, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, TRUE},
8335 {&vs_3, &ps_3, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8338 window = create_window();
8339 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8340 ok(!!d3d, "Failed to create a D3D object.\n");
8341 if (!(device = create_device(d3d, window, window, TRUE)))
8343 skip("Failed to create a D3D device, skipping tests.\n");
8344 goto done;
8347 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8348 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8349 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
8350 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
8352 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8353 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
8355 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip), 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
8356 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8357 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
8358 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8359 memcpy(data, quad_strip, sizeof(quad_strip));
8360 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
8361 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
8363 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list), 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
8364 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8365 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
8366 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8367 memcpy(data, quad_list, sizeof(quad_list));
8368 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
8369 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
8371 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8372 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
8374 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
8375 * the color fixups we have to do for FLAT shading will be dependent on that. */
8377 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
8379 if (tests[i].vs->version)
8381 if (caps.VertexShaderVersion >= tests[i].vs->version)
8383 hr = IDirect3DDevice9_CreateVertexShader(device, tests[i].vs->code, &vs);
8384 ok(hr == D3D_OK, "Failed to create vertex shader, hr %#x.\n", hr);
8385 hr = IDirect3DDevice9_SetVertexShader(device, vs);
8386 ok(hr == D3D_OK, "Failed to set vertex shader, hr %#x.\n", hr);
8388 else
8390 skip("Shader version unsupported, skipping some tests.\n");
8391 continue;
8394 else
8396 vs = NULL;
8398 if (tests[i].ps->version)
8400 if (caps.PixelShaderVersion >= tests[i].ps->version)
8402 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].ps->code, &ps);
8403 ok(hr == D3D_OK, "Failed to create pixel shader, hr %#x.\n", hr);
8404 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8405 ok(hr == D3D_OK, "Failed to set pixel shader, hr %#x.\n", hr);
8407 else
8409 skip("Shader version unsupported, skipping some tests.\n");
8410 if (vs)
8412 IDirect3DDevice9_SetVertexShader(device, NULL);
8413 IDirect3DVertexShader9_Release(vs);
8415 continue;
8418 else
8420 ps = NULL;
8423 hr = IDirect3DDevice9_SetStreamSource(device, 0,
8424 tests[i].primtype == D3DPT_TRIANGLESTRIP ? vb_strip : vb_list, 0, sizeof(quad_strip[0]));
8425 ok(hr == D3D_OK, "Failed to set stream source, hr %#x.\n", hr);
8427 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
8428 ok(hr == D3D_OK, "Failed to clear, hr %#x.\n", hr);
8430 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shademode);
8431 ok(hr == D3D_OK, "Failed to set shade mode, hr %#x.\n", hr);
8433 hr = IDirect3DDevice9_BeginScene(device);
8434 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8435 hr = IDirect3DDevice9_DrawPrimitive(device, tests[i].primtype, 0, 2);
8436 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8437 hr = IDirect3DDevice9_EndScene(device);
8438 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8440 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
8441 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
8443 /* For D3DSHADE_FLAT it should take the color of the first vertex of
8444 * each triangle. This requires EXT_provoking_vertex or similar
8445 * functionality being available. */
8446 /* PHONG should be the same as GOURAUD, since no hardware implements
8447 * this. */
8448 todo_wine_if (tests[i].todo)
8450 ok(color_match(color0, tests[i].color0, 1), "Test %u shading has color0 %08x, expected %08x.\n",
8451 i, color0, tests[i].color0);
8452 ok(color_match(color1, tests[i].color1, 1), "Test %u shading has color1 %08x, expected %08x.\n",
8453 i, color1, tests[i].color1);
8455 IDirect3DDevice9_SetVertexShader(device, NULL);
8456 IDirect3DDevice9_SetPixelShader(device, NULL);
8458 if (ps)
8459 IDirect3DPixelShader9_Release(ps);
8460 if (vs)
8461 IDirect3DVertexShader9_Release(vs);
8464 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8465 ok(hr == D3D_OK, "Failed to present, hr %#x.\n", hr);
8467 IDirect3DVertexBuffer9_Release(vb_strip);
8468 IDirect3DVertexBuffer9_Release(vb_list);
8469 refcount = IDirect3DDevice9_Release(device);
8470 ok(!refcount, "Device has %u references left.\n", refcount);
8471 done:
8472 IDirect3D9_Release(d3d);
8473 DestroyWindow(window);
8476 static void test_blend(void)
8478 IDirect3DSurface9 *backbuffer, *offscreen;
8479 IDirect3DTexture9 *offscreenTexture;
8480 IDirect3DDevice9 *device;
8481 IDirect3D9 *d3d;
8482 D3DCOLOR color;
8483 ULONG refcount;
8484 HWND window;
8485 HRESULT hr;
8487 static const struct
8489 struct vec3 position;
8490 DWORD diffuse;
8492 quad1[] =
8494 {{-1.0f, -1.0f, 0.1f}, 0x4000ff00},
8495 {{-1.0f, 0.0f, 0.1f}, 0x4000ff00},
8496 {{ 1.0f, -1.0f, 0.1f}, 0x4000ff00},
8497 {{ 1.0f, 0.0f, 0.1f}, 0x4000ff00},
8499 quad2[] =
8501 {{-1.0f, 0.0f, 0.1f}, 0xc00000ff},
8502 {{-1.0f, 1.0f, 0.1f}, 0xc00000ff},
8503 {{ 1.0f, 0.0f, 0.1f}, 0xc00000ff},
8504 {{ 1.0f, 1.0f, 0.1f}, 0xc00000ff},
8506 static const float composite_quad[][5] =
8508 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
8509 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
8510 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
8511 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
8514 window = create_window();
8515 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8516 ok(!!d3d, "Failed to create a D3D object.\n");
8517 if (!(device = create_device(d3d, window, window, TRUE)))
8519 skip("Failed to create a D3D device, skipping tests.\n");
8520 goto done;
8523 /* Clear the render target with alpha = 0.5 */
8524 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x80ff0000, 1.0f, 0);
8525 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8527 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
8528 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8529 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
8531 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8532 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8534 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8535 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8537 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8538 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
8540 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8541 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8542 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8543 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8544 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8545 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8546 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8547 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8548 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8549 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8551 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8552 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8553 hr = IDirect3DDevice9_BeginScene(device);
8554 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8556 /* Draw two quads, one with src alpha blending, one with dest alpha
8557 * blending. */
8558 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8559 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8560 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8561 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8562 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8563 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8565 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
8566 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8567 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
8568 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8569 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8570 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8572 /* Switch to the offscreen buffer, and redo the testing. The offscreen
8573 * render target doesn't have an alpha channel. DESTALPHA and INVDESTALPHA
8574 * "don't work" on render targets without alpha channel, they give
8575 * essentially ZERO and ONE blend factors. */
8576 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8577 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8578 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x80ff0000, 1.0f, 0);
8579 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8581 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8582 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8583 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8584 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8585 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8586 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8588 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
8589 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8590 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
8591 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8592 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8593 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8595 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8596 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8598 /* Render the offscreen texture onto the frame buffer to be able to
8599 * compare it regularly. Disable alpha blending for the final
8600 * composition. */
8601 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8602 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8603 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8604 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8606 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8607 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
8608 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
8609 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8611 hr = IDirect3DDevice9_EndScene(device);
8612 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8614 color = getPixelColor(device, 160, 360);
8615 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
8616 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
8618 color = getPixelColor(device, 160, 120);
8619 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
8620 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
8622 color = getPixelColor(device, 480, 360);
8623 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
8624 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
8626 color = getPixelColor(device, 480, 120);
8627 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
8628 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
8630 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8632 IDirect3DSurface9_Release(backbuffer);
8633 IDirect3DTexture9_Release(offscreenTexture);
8634 IDirect3DSurface9_Release(offscreen);
8635 refcount = IDirect3DDevice9_Release(device);
8636 ok(!refcount, "Device has %u references left.\n", refcount);
8637 done:
8638 IDirect3D9_Release(d3d);
8639 DestroyWindow(window);
8642 static void fixed_function_decl_test(void)
8644 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
8645 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_nocolor, *dcl_positiont;
8646 IDirect3DVertexBuffer9 *vb, *vb2;
8647 IDirect3DDevice9 *device;
8648 BOOL s_ok, ub_ok, f_ok;
8649 DWORD color, size, i;
8650 IDirect3D9 *d3d;
8651 ULONG refcount;
8652 D3DCAPS9 caps;
8653 HWND window;
8654 void *data;
8655 HRESULT hr;
8657 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
8658 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8659 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8660 D3DDECL_END()
8662 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
8663 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8664 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8665 D3DDECL_END()
8667 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
8668 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8669 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8670 D3DDECL_END()
8672 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
8673 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8674 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8675 D3DDECL_END()
8677 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
8678 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8679 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8680 D3DDECL_END()
8682 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
8683 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8684 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8685 D3DDECL_END()
8687 static const D3DVERTEXELEMENT9 decl_elements_nocolor[] = {
8688 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8689 D3DDECL_END()
8691 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
8692 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
8693 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8694 D3DDECL_END()
8696 static const struct
8698 struct vec3 position;
8699 DWORD diffuse;
8701 quad1[] = /* D3DCOLOR */
8703 {{-1.0f, -1.0f, 0.1f}, 0x00ffff00},
8704 {{-1.0f, 0.0f, 0.1f}, 0x00ffff00},
8705 {{ 0.0f, -1.0f, 0.1f}, 0x00ffff00},
8706 {{ 0.0f, 0.0f, 0.1f}, 0x00ffff00},
8708 quad2[] = /* UBYTE4N */
8710 {{-1.0f, 0.0f, 0.1f}, 0x00ffff00},
8711 {{-1.0f, 1.0f, 0.1f}, 0x00ffff00},
8712 {{ 0.0f, 0.0f, 0.1f}, 0x00ffff00},
8713 {{ 0.0f, 1.0f, 0.1f}, 0x00ffff00},
8715 static const struct
8717 struct vec3 position;
8718 struct { unsigned short x, y, z, w; } color;
8720 quad3[] = /* USHORT4N */
8722 {{0.0f, -1.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8723 {{0.0f, 0.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8724 {{1.0f, -1.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8725 {{1.0f, 0.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8727 static const struct
8729 struct vec3 position;
8730 struct vec4 color;
8732 quad4[] =
8734 {{0.0f, 0.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8735 {{0.0f, 1.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8736 {{1.0f, 0.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8737 {{1.0f, 1.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8739 static const DWORD colors[] =
8741 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8742 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8743 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8744 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8745 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8746 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8747 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8748 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8749 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8750 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8751 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8752 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8753 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8754 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8755 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8756 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8758 static const float quads[] =
8760 -1.0f, -1.0f, 0.1f,
8761 -1.0f, 0.0f, 0.1f,
8762 0.0f, -1.0f, 0.1f,
8763 0.0f, 0.0f, 0.1f,
8765 0.0f, -1.0f, 0.1f,
8766 0.0f, 0.0f, 0.1f,
8767 1.0f, -1.0f, 0.1f,
8768 1.0f, 0.0f, 0.1f,
8770 0.0f, 0.0f, 0.1f,
8771 0.0f, 1.0f, 0.1f,
8772 1.0f, 0.0f, 0.1f,
8773 1.0f, 1.0f, 0.1f,
8775 -1.0f, 0.0f, 0.1f,
8776 -1.0f, 1.0f, 0.1f,
8777 0.0f, 0.0f, 0.1f,
8778 0.0f, 1.0f, 0.1f,
8780 static const struct
8782 struct vec4 position;
8783 DWORD diffuse;
8785 quad_transformed[] =
8787 {{ 90.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
8788 {{570.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
8789 {{ 90.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
8790 {{570.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
8793 window = create_window();
8794 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8795 ok(!!d3d, "Failed to create a D3D object.\n");
8796 if (!(device = create_device(d3d, window, window, TRUE)))
8798 skip("Failed to create a D3D device, skipping tests.\n");
8799 goto done;
8802 memset(&caps, 0, sizeof(caps));
8803 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8804 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
8806 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
8807 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8809 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
8810 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8811 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
8812 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
8813 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
8814 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8815 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
8816 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
8817 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8818 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
8819 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8820 } else {
8821 trace("D3DDTCAPS_UBYTE4N not supported\n");
8822 dcl_ubyte_2 = NULL;
8823 dcl_ubyte = NULL;
8825 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
8826 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8827 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_nocolor, &dcl_nocolor);
8828 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8829 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
8830 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8832 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
8833 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
8834 0, 0, D3DPOOL_MANAGED, &vb, NULL);
8835 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8837 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8838 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
8840 hr = IDirect3DDevice9_BeginScene(device);
8841 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8843 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
8844 if (dcl_color)
8846 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
8847 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8848 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8849 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8852 /* Tests with non-standard fixed function types fail on the refrast. The
8853 * ATI driver partially accepts them, the NVIDIA driver accepts them all.
8854 * All those differences even though we're using software vertex
8855 * processing. Doh! */
8856 if (dcl_ubyte)
8858 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
8859 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8860 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8861 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8862 ub_ok = SUCCEEDED(hr);
8865 if (dcl_short)
8867 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
8868 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8869 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
8870 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8871 s_ok = SUCCEEDED(hr);
8874 if (dcl_float)
8876 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
8877 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8878 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
8879 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8880 f_ok = SUCCEEDED(hr);
8883 hr = IDirect3DDevice9_EndScene(device);
8884 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8886 if(dcl_short) {
8887 color = getPixelColor(device, 480, 360);
8888 ok(color == 0x000000ff || !s_ok,
8889 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
8891 if(dcl_ubyte) {
8892 color = getPixelColor(device, 160, 120);
8893 ok(color == 0x0000ffff || !ub_ok,
8894 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
8896 if(dcl_color) {
8897 color = getPixelColor(device, 160, 360);
8898 ok(color == 0x00ffff00,
8899 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
8901 if(dcl_float) {
8902 color = getPixelColor(device, 480, 120);
8903 ok(color == 0x00ff0000 || !f_ok,
8904 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
8906 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8908 /* The following test with vertex buffers doesn't serve to find out new
8909 * information from windows. It is a plain regression test because wined3d
8910 * uses different codepaths for attribute conversion with vertex buffers.
8911 * It makes sure that the vertex buffer one works, while the above tests
8912 * whether the immediate mode code works. */
8913 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
8914 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
8915 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8916 hr = IDirect3DDevice9_BeginScene(device);
8917 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8919 if (dcl_color)
8921 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
8922 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8923 memcpy(data, quad1, sizeof(quad1));
8924 hr = IDirect3DVertexBuffer9_Unlock(vb);
8925 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8926 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
8927 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8928 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
8929 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8930 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8931 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8934 if (dcl_ubyte)
8936 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
8937 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8938 memcpy(data, quad2, sizeof(quad2));
8939 hr = IDirect3DVertexBuffer9_Unlock(vb);
8940 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8941 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
8942 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8943 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
8944 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8945 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8946 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8947 ub_ok = SUCCEEDED(hr);
8950 if (dcl_short)
8952 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
8953 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8954 memcpy(data, quad3, sizeof(quad3));
8955 hr = IDirect3DVertexBuffer9_Unlock(vb);
8956 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8957 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
8958 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8959 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
8960 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8961 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8962 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8963 s_ok = SUCCEEDED(hr);
8966 if (dcl_float)
8968 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
8969 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8970 memcpy(data, quad4, sizeof(quad4));
8971 hr = IDirect3DVertexBuffer9_Unlock(vb);
8972 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8973 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
8974 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8975 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
8976 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8977 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8978 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8979 f_ok = SUCCEEDED(hr);
8982 hr = IDirect3DDevice9_EndScene(device);
8983 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8985 if(dcl_short) {
8986 color = getPixelColor(device, 480, 360);
8987 ok(color == 0x000000ff || !s_ok,
8988 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
8990 if(dcl_ubyte) {
8991 color = getPixelColor(device, 160, 120);
8992 ok(color == 0x0000ffff || !ub_ok,
8993 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
8995 if(dcl_color) {
8996 color = getPixelColor(device, 160, 360);
8997 ok(color == 0x00ffff00,
8998 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
9000 if(dcl_float) {
9001 color = getPixelColor(device, 480, 120);
9002 ok(color == 0x00ff0000 || !f_ok,
9003 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
9005 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9007 /* Test with no diffuse color attribute. */
9008 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9009 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9011 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_nocolor);
9012 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9013 hr = IDirect3DDevice9_BeginScene(device);
9014 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9015 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quads, sizeof(float) * 3);
9016 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9017 hr = IDirect3DDevice9_EndScene(device);
9018 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9020 color = getPixelColor(device, 160, 360);
9021 ok(color == 0x00ffffff, "Got unexpected color 0x%08x in the no color attribute test.\n", color);
9023 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9025 /* Test what happens with specular lighting enabled and no specular color attribute. */
9026 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
9027 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
9028 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9029 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
9030 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#x.\n", hr);
9031 hr = IDirect3DDevice9_BeginScene(device);
9032 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9034 if (dcl_color)
9036 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
9037 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9038 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9039 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9041 if (dcl_ubyte)
9043 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
9044 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9045 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9046 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9047 ub_ok = SUCCEEDED(hr);
9049 if (dcl_short)
9051 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
9052 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9053 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
9054 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9055 s_ok = SUCCEEDED(hr);
9057 if (dcl_float)
9059 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
9060 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9061 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
9062 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9063 f_ok = SUCCEEDED(hr);
9066 hr = IDirect3DDevice9_EndScene(device);
9067 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9068 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARENABLE, FALSE);
9069 ok(SUCCEEDED(hr), "Failed to disable specular lighting, hr %#x.\n", hr);
9071 if (dcl_short)
9073 color = getPixelColor(device, 480, 360);
9074 ok(color == 0x000000ff || !s_ok,
9075 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff.\n", color);
9077 if (dcl_ubyte)
9079 color = getPixelColor(device, 160, 120);
9080 ok(color == 0x0000ffff || !ub_ok,
9081 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff.\n", color);
9083 if (dcl_color)
9085 color = getPixelColor(device, 160, 360);
9086 ok(color == 0x00ffff00,
9087 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00.\n", color);
9089 if (dcl_float)
9091 color = getPixelColor(device, 480, 120);
9092 ok(color == 0x00ff0000 || !f_ok,
9093 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000.\n", color);
9095 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9097 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
9098 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9099 memcpy(data, quad_transformed, sizeof(quad_transformed));
9100 hr = IDirect3DVertexBuffer9_Unlock(vb);
9101 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
9103 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
9104 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
9106 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9107 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9109 hr = IDirect3DDevice9_BeginScene(device);
9110 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9111 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
9112 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
9113 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9114 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9115 hr = IDirect3DDevice9_EndScene(device);
9116 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9118 color = getPixelColor(device, 88, 108);
9119 ok(color == 0x000000ff,
9120 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
9121 color = getPixelColor(device, 92, 108);
9122 ok(color == 0x000000ff,
9123 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
9124 color = getPixelColor(device, 88, 112);
9125 ok(color == 0x000000ff,
9126 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
9127 color = getPixelColor(device, 92, 112);
9128 ok(color == 0x00ffff00,
9129 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
9131 color = getPixelColor(device, 568, 108);
9132 ok(color == 0x000000ff,
9133 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
9134 color = getPixelColor(device, 572, 108);
9135 ok(color == 0x000000ff,
9136 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
9137 color = getPixelColor(device, 568, 112);
9138 ok(color == 0x00ffff00,
9139 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
9140 color = getPixelColor(device, 572, 112);
9141 ok(color == 0x000000ff,
9142 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
9144 color = getPixelColor(device, 88, 298);
9145 ok(color == 0x000000ff,
9146 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
9147 color = getPixelColor(device, 92, 298);
9148 ok(color == 0x00ffff00,
9149 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
9150 color = getPixelColor(device, 88, 302);
9151 ok(color == 0x000000ff,
9152 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
9153 color = getPixelColor(device, 92, 302);
9154 ok(color == 0x000000ff,
9155 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
9157 color = getPixelColor(device, 568, 298);
9158 ok(color == 0x00ffff00,
9159 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
9160 color = getPixelColor(device, 572, 298);
9161 ok(color == 0x000000ff,
9162 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
9163 color = getPixelColor(device, 568, 302);
9164 ok(color == 0x000000ff,
9165 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
9166 color = getPixelColor(device, 572, 302);
9167 ok(color == 0x000000ff,
9168 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
9170 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9172 /* This test is pointless without those two declarations: */
9173 if((!dcl_color_2) || (!dcl_ubyte_2)) {
9174 skip("color-ubyte switching test declarations aren't supported\n");
9175 goto out;
9178 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
9179 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9180 memcpy(data, quads, sizeof(quads));
9181 hr = IDirect3DVertexBuffer9_Unlock(vb);
9182 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
9183 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
9184 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9185 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9186 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
9187 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9188 memcpy(data, colors, sizeof(colors));
9189 hr = IDirect3DVertexBuffer9_Unlock(vb2);
9190 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
9192 for(i = 0; i < 2; i++) {
9193 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9194 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9196 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
9197 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
9198 if(i == 0) {
9199 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
9200 } else {
9201 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
9203 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
9205 hr = IDirect3DDevice9_BeginScene(device);
9206 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9208 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
9209 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9210 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9211 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9212 ub_ok = SUCCEEDED(hr);
9214 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
9215 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9216 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
9217 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9219 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
9220 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9221 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
9222 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9223 ub_ok = (SUCCEEDED(hr) && ub_ok);
9225 hr = IDirect3DDevice9_EndScene(device);
9226 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9228 if(i == 0) {
9229 color = getPixelColor(device, 480, 360);
9230 ok(color == 0x00ff0000,
9231 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
9232 color = getPixelColor(device, 160, 120);
9233 ok(color == 0x00ffffff,
9234 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
9235 color = getPixelColor(device, 160, 360);
9236 ok(color == 0x000000ff || !ub_ok,
9237 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
9238 color = getPixelColor(device, 480, 120);
9239 ok(color == 0x000000ff || !ub_ok,
9240 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
9241 } else {
9242 color = getPixelColor(device, 480, 360);
9243 ok(color == 0x000000ff,
9244 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
9245 color = getPixelColor(device, 160, 120);
9246 ok(color == 0x00ffffff,
9247 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
9248 color = getPixelColor(device, 160, 360);
9249 ok(color == 0x00ff0000 || !ub_ok,
9250 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
9251 color = getPixelColor(device, 480, 120);
9252 ok(color == 0x00ff0000 || !ub_ok,
9253 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
9255 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9258 IDirect3DVertexBuffer9_Release(vb2);
9259 out:
9260 IDirect3DVertexBuffer9_Release(vb);
9261 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
9262 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
9263 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
9264 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
9265 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
9266 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
9267 IDirect3DVertexDeclaration9_Release(dcl_nocolor);
9268 IDirect3DVertexDeclaration9_Release(dcl_positiont);
9269 refcount = IDirect3DDevice9_Release(device);
9270 ok(!refcount, "Device has %u references left.\n", refcount);
9271 done:
9272 IDirect3D9_Release(d3d);
9273 DestroyWindow(window);
9276 static void test_vshader_float16(void)
9278 IDirect3DVertexDeclaration9 *vdecl = NULL;
9279 IDirect3DVertexBuffer9 *buffer = NULL;
9280 IDirect3DVertexShader9 *shader;
9281 IDirect3DDevice9 *device;
9282 IDirect3D9 *d3d;
9283 ULONG refcount;
9284 D3DCAPS9 caps;
9285 DWORD color;
9286 HWND window;
9287 void *data;
9288 HRESULT hr;
9290 static const D3DVERTEXELEMENT9 decl_elements[] =
9292 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9293 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9294 D3DDECL_END()
9296 static const DWORD shader_code[] =
9298 0xfffe0101, /* vs_1_1 */
9299 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9300 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
9301 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
9302 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
9303 0x0000ffff,
9305 static const struct vertex_float16color
9307 float x, y, z;
9308 DWORD c1, c2;
9310 quad[] =
9312 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
9313 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
9314 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
9315 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
9317 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
9318 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
9319 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
9320 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
9322 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
9323 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
9324 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
9325 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
9327 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
9328 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
9329 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
9330 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
9333 window = create_window();
9334 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9335 ok(!!d3d, "Failed to create a D3D object.\n");
9336 if (!(device = create_device(d3d, window, window, TRUE)))
9338 skip("Failed to create a D3D device, skipping tests.\n");
9339 goto done;
9342 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9343 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
9344 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
9346 skip("No vs_3_0 support, skipping tests.\n");
9347 IDirect3DDevice9_Release(device);
9348 goto done;
9351 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff102030, 1.0f, 0);
9352 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9354 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
9355 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
9356 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9357 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9358 hr = IDirect3DDevice9_SetVertexShader(device, shader);
9359 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9361 hr = IDirect3DDevice9_BeginScene(device);
9362 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9363 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
9364 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9365 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
9366 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9367 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
9368 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9369 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
9370 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9371 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
9372 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9373 hr = IDirect3DDevice9_EndScene(device);
9374 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9376 color = getPixelColor(device, 480, 360);
9377 ok(color == 0x00ff0000,
9378 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
9379 color = getPixelColor(device, 160, 120);
9380 ok(color == 0x00000000,
9381 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
9382 color = getPixelColor(device, 160, 360);
9383 ok(color == 0x0000ff00,
9384 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
9385 color = getPixelColor(device, 480, 120);
9386 ok(color == 0x000000ff,
9387 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
9388 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9390 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
9391 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9393 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
9394 D3DPOOL_MANAGED, &buffer, NULL);
9395 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
9396 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
9397 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
9398 memcpy(data, quad, sizeof(quad));
9399 hr = IDirect3DVertexBuffer9_Unlock(buffer);
9400 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
9401 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
9402 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
9404 hr = IDirect3DDevice9_BeginScene(device);
9405 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9406 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9407 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9408 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
9409 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9410 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
9411 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9412 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
9413 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9414 hr = IDirect3DDevice9_EndScene(device);
9415 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9417 color = getPixelColor(device, 480, 360);
9418 ok(color == 0x00ff0000,
9419 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
9420 color = getPixelColor(device, 160, 120);
9421 ok(color == 0x00000000,
9422 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
9423 color = getPixelColor(device, 160, 360);
9424 ok(color == 0x0000ff00,
9425 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
9426 color = getPixelColor(device, 480, 120);
9427 ok(color == 0x000000ff,
9428 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
9429 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9431 IDirect3DVertexDeclaration9_Release(vdecl);
9432 IDirect3DVertexShader9_Release(shader);
9433 IDirect3DVertexBuffer9_Release(buffer);
9434 refcount = IDirect3DDevice9_Release(device);
9435 ok(!refcount, "Device has %u references left.\n", refcount);
9436 done:
9437 IDirect3D9_Release(d3d);
9438 DestroyWindow(window);
9441 static void conditional_np2_repeat_test(void)
9443 IDirect3DTexture9 *texture;
9444 IDirect3DDevice9 *device;
9445 D3DLOCKED_RECT rect;
9446 unsigned int x, y;
9447 DWORD *dst, color;
9448 IDirect3D9 *d3d;
9449 ULONG refcount;
9450 D3DCAPS9 caps;
9451 HWND window;
9452 HRESULT hr;
9454 static const float quad[] =
9456 -1.0f, -1.0f, 0.1f, -0.2f, -0.2f,
9457 -1.0f, 1.0f, 0.1f, -0.2f, 1.2f,
9458 1.0f, -1.0f, 0.1f, 1.2f, -0.2f,
9459 1.0f, 1.0f, 0.1f, 1.2f, 1.2f,
9462 window = create_window();
9463 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9464 ok(!!d3d, "Failed to create a D3D object.\n");
9465 if (!(device = create_device(d3d, window, window, TRUE)))
9467 skip("Failed to create a D3D device, skipping tests.\n");
9468 goto done;
9471 memset(&caps, 0, sizeof(caps));
9472 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9473 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
9474 if (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)
9476 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
9477 ok(caps.TextureCaps & D3DPTEXTURECAPS_POW2,
9478 "Card has conditional NP2 support without power of two restriction set\n");
9480 else if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
9482 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
9483 IDirect3DDevice9_Release(device);
9484 goto done;
9486 else
9488 skip("Card has unconditional NP2 support, skipping conditional NP2 tests\n");
9489 IDirect3DDevice9_Release(device);
9490 goto done;
9493 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
9494 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9496 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9497 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9499 memset(&rect, 0, sizeof(rect));
9500 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
9501 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9502 for(y = 0; y < 10; y++) {
9503 for(x = 0; x < 10; x++) {
9504 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
9505 if(x == 0 || x == 9 || y == 0 || y == 9) {
9506 *dst = 0x00ff0000;
9507 } else {
9508 *dst = 0x000000ff;
9512 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9513 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9515 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
9516 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9517 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9518 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
9519 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
9520 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
9521 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
9522 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
9523 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9524 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
9526 hr = IDirect3DDevice9_BeginScene(device);
9527 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9528 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9529 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9530 hr = IDirect3DDevice9_EndScene(device);
9531 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9533 color = getPixelColor(device, 1, 1);
9534 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
9535 color = getPixelColor(device, 639, 479);
9536 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
9538 color = getPixelColor(device, 135, 101);
9539 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
9540 color = getPixelColor(device, 140, 101);
9541 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
9542 color = getPixelColor(device, 135, 105);
9543 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
9544 color = getPixelColor(device, 140, 105);
9545 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
9547 color = getPixelColor(device, 135, 376);
9548 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
9549 color = getPixelColor(device, 140, 376);
9550 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
9551 color = getPixelColor(device, 135, 379);
9552 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
9553 color = getPixelColor(device, 140, 379);
9554 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
9556 color = getPixelColor(device, 500, 101);
9557 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
9558 color = getPixelColor(device, 504, 101);
9559 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
9560 color = getPixelColor(device, 500, 105);
9561 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
9562 color = getPixelColor(device, 504, 105);
9563 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
9565 color = getPixelColor(device, 500, 376);
9566 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
9567 color = getPixelColor(device, 504, 376);
9568 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
9569 color = getPixelColor(device, 500, 380);
9570 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
9571 color = getPixelColor(device, 504, 380);
9572 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
9574 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9576 IDirect3DTexture9_Release(texture);
9577 refcount = IDirect3DDevice9_Release(device);
9578 ok(!refcount, "Device has %u references left.\n", refcount);
9579 done:
9580 IDirect3D9_Release(d3d);
9581 DestroyWindow(window);
9584 static void vface_register_test(void)
9586 IDirect3DSurface9 *surface, *backbuffer;
9587 IDirect3DVertexShader9 *vshader;
9588 IDirect3DPixelShader9 *shader;
9589 IDirect3DTexture9 *texture;
9590 IDirect3DDevice9 *device;
9591 IDirect3D9 *d3d;
9592 ULONG refcount;
9593 D3DCAPS9 caps;
9594 DWORD color;
9595 HWND window;
9596 HRESULT hr;
9598 static const DWORD shader_code[] =
9600 0xffff0300, /* ps_3_0 */
9601 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9602 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
9603 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
9604 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
9605 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
9606 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
9607 0x0000ffff /* END */
9609 static const DWORD vshader_code[] =
9611 0xfffe0300, /* vs_3_0 */
9612 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9613 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
9614 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
9615 0x0000ffff /* end */
9617 static const float quad[] =
9619 -1.0f, -1.0f, 0.1f,
9620 1.0f, -1.0f, 0.1f,
9621 -1.0f, 0.0f, 0.1f,
9623 1.0f, -1.0f, 0.1f,
9624 1.0f, 0.0f, 0.1f,
9625 -1.0f, 0.0f, 0.1f,
9627 -1.0f, 0.0f, 0.1f,
9628 -1.0f, 1.0f, 0.1f,
9629 1.0f, 0.0f, 0.1f,
9631 1.0f, 0.0f, 0.1f,
9632 -1.0f, 1.0f, 0.1f,
9633 1.0f, 1.0f, 0.1f,
9635 static const float blit[] =
9637 0.0f, -1.0f, 0.1f, 0.0f, 0.0f,
9638 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
9639 0.0f, 1.0f, 0.1f, 0.0f, 1.0f,
9640 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
9643 window = create_window();
9644 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9645 ok(!!d3d, "Failed to create a D3D object.\n");
9646 if (!(device = create_device(d3d, window, window, TRUE)))
9648 skip("Failed to create a D3D device, skipping tests.\n");
9649 goto done;
9652 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9653 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
9654 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
9656 skip("No shader model 3 support, skipping tests.\n");
9657 IDirect3DDevice9_Release(device);
9658 goto done;
9661 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
9662 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9663 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
9664 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
9665 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
9666 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9667 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
9668 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
9669 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
9670 ok(SUCCEEDED(hr), "Failed to set cull mode, hr %#x.\n", hr);
9671 hr = IDirect3DDevice9_SetPixelShader(device, shader);
9672 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
9673 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
9674 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9675 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9676 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
9677 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9678 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
9680 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
9681 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9683 hr = IDirect3DDevice9_BeginScene(device);
9684 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9686 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
9687 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
9688 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
9689 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9690 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9691 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
9692 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9693 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9694 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
9695 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
9696 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9698 /* Blit the texture onto the back buffer to make it visible */
9699 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9700 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
9701 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9702 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9703 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
9704 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
9705 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9706 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
9707 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9708 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
9709 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9710 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9711 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
9712 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9714 hr = IDirect3DDevice9_EndScene(device);
9715 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9717 color = getPixelColor(device, 160, 360);
9718 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
9719 color = getPixelColor(device, 160, 120);
9720 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
9721 color = getPixelColor(device, 480, 360);
9722 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
9723 color = getPixelColor(device, 480, 120);
9724 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
9725 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9726 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
9728 IDirect3DPixelShader9_Release(shader);
9729 IDirect3DVertexShader9_Release(vshader);
9730 IDirect3DSurface9_Release(surface);
9731 IDirect3DSurface9_Release(backbuffer);
9732 IDirect3DTexture9_Release(texture);
9733 refcount = IDirect3DDevice9_Release(device);
9734 ok(!refcount, "Device has %u references left.\n", refcount);
9735 done:
9736 IDirect3D9_Release(d3d);
9737 DestroyWindow(window);
9740 static void fixed_function_bumpmap_test(void)
9742 IDirect3DVertexDeclaration9 *vertex_declaration;
9743 IDirect3DTexture9 *texture, *tex1, *tex2;
9744 D3DLOCKED_RECT locked_rect;
9745 IDirect3DDevice9 *device;
9746 BOOL L6V5U5_supported;
9747 float scale, offset;
9748 IDirect3D9 *d3d;
9749 unsigned int i;
9750 D3DCOLOR color;
9751 ULONG refcount;
9752 D3DCAPS9 caps;
9753 HWND window;
9754 HRESULT hr;
9756 static const float quad[][7] =
9758 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
9759 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
9760 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
9761 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
9763 static const D3DVERTEXELEMENT9 decl_elements[] =
9765 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9766 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9767 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
9768 D3DDECL_END()
9770 /* use asymmetric matrix to test loading */
9771 static const float bumpenvmat[4] = {0.0f, 0.5f, -0.5f, 0.0f};
9773 window = create_window();
9774 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9775 ok(!!d3d, "Failed to create a D3D object.\n");
9776 if (!(device = create_device(d3d, window, window, TRUE)))
9778 skip("Failed to create a D3D device, skipping tests.\n");
9779 goto done;
9782 memset(&caps, 0, sizeof(caps));
9783 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9784 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
9785 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP))
9787 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
9788 IDirect3DDevice9_Release(device);
9789 goto done;
9792 /* This check is disabled, some Windows drivers do not handle
9793 * D3DUSAGE_QUERY_LEGACYBUMPMAP properly. They report that it is not
9794 * supported, but after that bump mapping works properly. So just test if
9795 * the format is generally supported, and check the BUMPENVMAP flag. */
9796 L6V5U5_supported = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
9797 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_L6V5U5));
9798 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
9799 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_V8U8)))
9801 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
9802 IDirect3DDevice9_Release(device);
9803 return;
9806 /* Generate the textures */
9807 generate_bumpmap_textures(device);
9809 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
9810 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9811 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
9812 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9813 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
9814 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9815 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
9816 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9818 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
9819 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9820 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
9821 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9822 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
9823 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9825 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9826 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9827 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9828 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9829 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
9830 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9832 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9833 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9835 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9836 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
9838 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff00ff, 1.0f, 0);
9839 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
9841 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9842 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
9843 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9844 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
9846 hr = IDirect3DDevice9_BeginScene(device);
9847 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
9849 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9850 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
9852 hr = IDirect3DDevice9_EndScene(device);
9853 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
9855 color = getPixelColor(device, 240, 60);
9856 ok(color_match(color, 0x005ea000, 4), "Got unexpected color 0x%08x.\n", color);
9857 color = getPixelColor(device, 400, 60);
9858 ok(color_match(color, 0x009ea000, 4), "Got unexpected color 0x%08x.\n", color);
9859 color = getPixelColor(device, 80, 180);
9860 ok(color_match(color, 0x005ea000, 4), "Got unexpected color 0x%08x.\n", color);
9861 color = getPixelColor(device, 560, 180);
9862 ok(color_match(color, 0x009ea000, 4), "Got unexpected color 0x%08x.\n", color);
9863 color = getPixelColor(device, 80, 300);
9864 ok(color_match(color, 0x005e6000, 4), "Got unexpected color 0x%08x.\n", color);
9865 color = getPixelColor(device, 560, 300);
9866 ok(color_match(color, 0x009e6000, 4), "Got unexpected color 0x%08x.\n", color);
9867 color = getPixelColor(device, 240, 420);
9868 ok(color_match(color, 0x005e6000, 4), "Got unexpected color 0x%08x.\n", color);
9869 color = getPixelColor(device, 400, 420);
9870 ok(color_match(color, 0x009e6000, 4), "Got unexpected color 0x%08x.\n", color);
9871 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9872 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9874 for(i = 0; i < 2; i++) {
9875 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
9876 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
9877 IDirect3DTexture9_Release(texture); /* For the GetTexture */
9878 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
9879 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
9880 IDirect3DTexture9_Release(texture); /* To destroy it */
9883 if (!L6V5U5_supported || !(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE))
9885 skip("L6V5U5 / D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping tests.\n");
9886 IDirect3DVertexDeclaration9_Release(vertex_declaration);
9887 IDirect3DDevice9_Release(device);
9888 goto done;
9891 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9892 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
9893 /* This test only tests the luminance part. The bumpmapping part was already tested above and
9894 * would only make this test more complicated
9896 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
9897 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9898 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
9899 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9901 memset(&locked_rect, 0, sizeof(locked_rect));
9902 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
9903 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9904 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
9905 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
9906 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9908 memset(&locked_rect, 0, sizeof(locked_rect));
9909 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
9910 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9911 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
9912 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
9913 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9915 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9916 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
9917 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
9918 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
9920 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
9921 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9922 scale = 2.0;
9923 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
9924 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9925 offset = 0.1;
9926 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
9927 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9929 hr = IDirect3DDevice9_BeginScene(device);
9930 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9931 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9932 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9933 hr = IDirect3DDevice9_EndScene(device);
9934 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9936 color = getPixelColor(device, 320, 240);
9937 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
9938 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
9939 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
9941 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
9942 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9943 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9945 /* Check a result scale factor > 1.0 */
9946 scale = 10;
9947 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
9948 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9949 offset = 10;
9950 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
9951 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9953 hr = IDirect3DDevice9_BeginScene(device);
9954 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9955 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9956 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9957 hr = IDirect3DDevice9_EndScene(device);
9958 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9960 color = getPixelColor(device, 320, 240);
9961 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
9962 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9963 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9965 /* Check clamping in the scale factor calculation */
9966 scale = 1000;
9967 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
9968 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9969 offset = -1;
9970 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
9971 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9973 hr = IDirect3DDevice9_BeginScene(device);
9974 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9975 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9976 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9977 hr = IDirect3DDevice9_EndScene(device);
9978 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9980 color = getPixelColor(device, 320, 240);
9981 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
9982 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9983 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9985 IDirect3DTexture9_Release(tex1);
9986 IDirect3DTexture9_Release(tex2);
9987 IDirect3DVertexDeclaration9_Release(vertex_declaration);
9988 refcount = IDirect3DDevice9_Release(device);
9989 ok(!refcount, "Device has %u references left.\n", refcount);
9990 done:
9991 IDirect3D9_Release(d3d);
9992 DestroyWindow(window);
9995 static void stencil_cull_test(void)
9997 IDirect3DDevice9 *device;
9998 IDirect3D9 *d3d;
9999 ULONG refcount;
10000 D3DCAPS9 caps;
10001 HWND window;
10002 HRESULT hr;
10003 static const float quad1[] =
10005 -1.0, -1.0, 0.1,
10006 0.0, -1.0, 0.1,
10007 -1.0, 0.0, 0.1,
10008 0.0, 0.0, 0.1,
10010 static const float quad2[] =
10012 0.0, -1.0, 0.1,
10013 1.0, -1.0, 0.1,
10014 0.0, 0.0, 0.1,
10015 1.0, 0.0, 0.1,
10017 static const float quad3[] =
10019 0.0, 0.0, 0.1,
10020 1.0, 0.0, 0.1,
10021 0.0, 1.0, 0.1,
10022 1.0, 1.0, 0.1,
10024 static const float quad4[] =
10026 -1.0, 0.0, 0.1,
10027 0.0, 0.0, 0.1,
10028 -1.0, 1.0, 0.1,
10029 0.0, 1.0, 0.1,
10031 struct
10033 struct vec3 position;
10034 DWORD diffuse;
10036 painter[] =
10038 {{-1.0f, -1.0f, 0.0f}, 0x00000000},
10039 {{ 1.0f, -1.0f, 0.0f}, 0x00000000},
10040 {{-1.0f, 1.0f, 0.0f}, 0x00000000},
10041 {{ 1.0f, 1.0f, 0.0f}, 0x00000000},
10043 static const WORD indices_cw[] = {0, 1, 3};
10044 static const WORD indices_ccw[] = {0, 2, 3};
10045 unsigned int i;
10046 DWORD color;
10048 window = create_window();
10049 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10050 ok(!!d3d, "Failed to create a D3D object.\n");
10051 if (!(device = create_device(d3d, window, window, TRUE)))
10053 skip("Cannot create a device with a D24S8 stencil buffer.\n");
10054 DestroyWindow(window);
10055 IDirect3D9_Release(d3d);
10056 return;
10058 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10059 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
10060 if (!(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED))
10062 skip("No two sided stencil support\n");
10063 goto cleanup;
10066 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
10067 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10068 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10069 ok(SUCCEEDED(hr), "Failed to set FVF,hr %#x.\n", hr);
10071 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10072 ok(hr == D3D_OK, "Failed to disable Z test, %#x.\n", hr);
10073 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10074 ok(hr == D3D_OK, "Failed to disable lighting, %#x.\n", hr);
10075 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
10076 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10077 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
10078 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10079 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
10080 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10081 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
10082 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10084 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
10085 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10086 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
10087 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10088 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
10089 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10091 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
10092 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10093 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
10094 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10096 /* First pass: Fill the stencil buffer with some values... */
10097 hr = IDirect3DDevice9_BeginScene(device);
10098 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10100 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
10101 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10102 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10103 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
10104 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10105 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10106 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
10107 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10109 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
10110 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10111 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
10112 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10113 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10114 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
10115 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10116 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10117 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
10118 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10120 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
10121 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10122 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10123 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
10124 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10125 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10126 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
10127 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10129 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
10130 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10131 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10132 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
10133 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10134 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10135 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
10136 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10138 hr = IDirect3DDevice9_EndScene(device);
10139 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10141 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
10142 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10143 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
10144 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10145 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
10146 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10147 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
10148 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10149 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
10150 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10151 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
10152 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10154 /* 2nd pass: Make the stencil values visible */
10155 hr = IDirect3DDevice9_BeginScene(device);
10156 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10157 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10158 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
10159 for (i = 0; i < 16; ++i)
10161 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
10162 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10164 painter[0].diffuse = (i * 16); /* Creates shades of blue */
10165 painter[1].diffuse = (i * 16);
10166 painter[2].diffuse = (i * 16);
10167 painter[3].diffuse = (i * 16);
10168 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
10169 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10171 hr = IDirect3DDevice9_EndScene(device);
10172 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10174 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
10175 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10177 color = getPixelColor(device, 160, 420);
10178 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
10179 color = getPixelColor(device, 160, 300);
10180 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
10182 color = getPixelColor(device, 480, 420);
10183 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
10184 color = getPixelColor(device, 480, 300);
10185 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
10187 color = getPixelColor(device, 160, 180);
10188 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
10189 color = getPixelColor(device, 160, 60);
10190 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
10192 color = getPixelColor(device, 480, 180);
10193 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
10194 color = getPixelColor(device, 480, 60);
10195 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
10197 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10198 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10200 cleanup:
10201 refcount = IDirect3DDevice9_Release(device);
10202 ok(!refcount, "Device has %u references left.\n", refcount);
10203 IDirect3D9_Release(d3d);
10204 DestroyWindow(window);
10207 static void test_fragment_coords(void)
10209 IDirect3DSurface9 *surface = NULL, *backbuffer;
10210 IDirect3DPixelShader9 *shader, *shader_frac;
10211 IDirect3DVertexShader9 *vshader;
10212 IDirect3DDevice9 *device;
10213 D3DLOCKED_RECT lr;
10214 IDirect3D9 *d3d;
10215 ULONG refcount;
10216 D3DCAPS9 caps;
10217 DWORD color;
10218 HWND window;
10219 HRESULT hr;
10220 DWORD *pos;
10222 static const DWORD shader_code[] =
10224 0xffff0300, /* ps_3_0 */
10225 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
10226 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
10227 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
10228 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
10229 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
10230 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
10231 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
10232 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
10233 0x0000ffff /* end */
10235 static const DWORD shader_frac_code[] =
10237 0xffff0300, /* ps_3_0 */
10238 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
10239 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
10240 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
10241 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
10242 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
10243 0x0000ffff /* end */
10245 static const DWORD vshader_code[] =
10247 0xfffe0300, /* vs_3_0 */
10248 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10249 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
10250 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
10251 0x0000ffff /* end */
10253 static const float quad[] =
10255 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
10256 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
10257 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
10258 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
10260 float constant[4] = {1.0, 0.0, 320, 240};
10262 window = create_window();
10263 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10264 ok(!!d3d, "Failed to create a D3D object.\n");
10265 if (!(device = create_device(d3d, window, window, TRUE)))
10267 skip("Failed to create a D3D device, skipping tests.\n");
10268 goto done;
10271 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10272 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
10273 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
10275 skip("No shader model 3 support, skipping tests.\n");
10276 IDirect3DDevice9_Release(device);
10277 goto done;
10280 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10281 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
10282 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
10283 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
10284 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
10285 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
10286 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
10287 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
10288 hr = IDirect3DDevice9_SetPixelShader(device, shader);
10289 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
10290 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
10291 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
10292 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10293 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
10294 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
10295 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
10297 hr = IDirect3DDevice9_BeginScene(device);
10298 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10299 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
10300 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
10301 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
10302 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10303 hr = IDirect3DDevice9_EndScene(device);
10304 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10306 /* This has to be pixel exact */
10307 color = getPixelColor(device, 319, 239);
10308 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
10309 color = getPixelColor(device, 320, 239);
10310 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
10311 color = getPixelColor(device, 319, 240);
10312 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
10313 color = getPixelColor(device, 320, 240);
10314 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
10315 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10317 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
10318 &surface, NULL);
10319 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
10320 hr = IDirect3DDevice9_BeginScene(device);
10321 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10322 constant[2] = 16; constant[3] = 16;
10323 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
10324 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
10325 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
10326 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10327 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
10328 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10329 hr = IDirect3DDevice9_EndScene(device);
10330 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10332 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
10333 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
10335 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
10336 color = *pos & 0x00ffffff;
10337 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
10338 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
10339 color = *pos & 0x00ffffff;
10340 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
10341 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
10342 color = *pos & 0x00ffffff;
10343 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
10344 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
10345 color = *pos & 0x00ffffff;
10346 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
10348 hr = IDirect3DSurface9_UnlockRect(surface);
10349 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
10351 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
10352 * have full control over the multisampling setting inside this test
10354 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
10355 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
10356 hr = IDirect3DDevice9_BeginScene(device);
10357 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10358 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
10359 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
10360 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
10361 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10362 hr = IDirect3DDevice9_EndScene(device);
10363 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10365 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10366 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
10368 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
10369 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
10371 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
10372 color = *pos & 0x00ffffff;
10373 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
10375 hr = IDirect3DSurface9_UnlockRect(surface);
10376 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
10378 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
10379 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
10380 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10381 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
10382 IDirect3DPixelShader9_Release(shader);
10383 IDirect3DPixelShader9_Release(shader_frac);
10384 IDirect3DVertexShader9_Release(vshader);
10385 if(surface) IDirect3DSurface9_Release(surface);
10386 IDirect3DSurface9_Release(backbuffer);
10387 refcount = IDirect3DDevice9_Release(device);
10388 ok(!refcount, "Device has %u references left.\n", refcount);
10389 done:
10390 IDirect3D9_Release(d3d);
10391 DestroyWindow(window);
10394 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
10396 D3DCOLOR color;
10398 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
10399 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
10400 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
10401 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
10402 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
10404 ++r;
10405 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
10406 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
10407 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
10408 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
10409 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
10411 return TRUE;
10414 static void test_pointsize(void)
10416 static const float a = 1.0f, b = 1.0f, c = 1.0f;
10417 float ptsize, ptsizemax_orig, ptsizemin_orig;
10418 IDirect3DSurface9 *rt, *backbuffer;
10419 IDirect3DTexture9 *tex1, *tex2;
10420 IDirect3DDevice9 *device;
10421 IDirect3DVertexShader9 *vs;
10422 IDirect3DPixelShader9 *ps;
10423 D3DLOCKED_RECT lr;
10424 IDirect3D9 *d3d;
10425 D3DCOLOR color;
10426 ULONG refcount;
10427 D3DCAPS9 caps;
10428 HWND window;
10429 HRESULT hr;
10430 unsigned int i, j;
10432 static const RECT rect = {0, 0, 128, 128};
10433 static const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000, 0x00000000, 0x00000000};
10434 static const DWORD tex2_data[4] = {0x00000000, 0x0000ff00, 0x00000000, 0x0000ff00};
10435 static const float vertices[] =
10437 64.0f, 64.0f, 0.1f,
10438 128.0f, 64.0f, 0.1f,
10439 192.0f, 64.0f, 0.1f,
10440 256.0f, 64.0f, 0.1f,
10441 320.0f, 64.0f, 0.1f,
10442 384.0f, 64.0f, 0.1f,
10443 448.0f, 64.0f, 0.1f,
10444 512.0f, 64.0f, 0.1f,
10446 static const struct
10448 float x, y, z;
10449 float point_size;
10451 vertex_pointsize = {64.0f, 64.0f, 0.1f, 48.0f},
10452 vertex_pointsize_scaled = {64.0f, 64.0f, 0.1f, 24.0f},
10453 vertex_pointsize_zero = {64.0f, 64.0f, 0.1f, 0.0f};
10454 /* Writing a texture coordinate from the shader is technically unnecessary, but is required
10455 * to make Windows AMD r500 drivers work. Without it, texture coordinates in the pixel
10456 * shaders are 0. */
10457 static const DWORD vshader_code[] =
10459 0xfffe0101, /* vs_1_1 */
10460 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10461 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10462 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10463 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10464 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
10465 0x00000001, 0xe00f0000, 0x90e40000, /* mov oT0, v0 */
10466 0x00000001, 0xe00f0001, 0x90e40000, /* mov oT1, v0 */
10467 0x0000ffff
10469 static const DWORD vshader_psize_code[] =
10471 0xfffe0101, /* vs_1_1 */
10472 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10473 0x0000001f, 0x80000004, 0x900f0001, /* dcl_psize v1 */
10474 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10475 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10476 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10477 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
10478 0x00000001, 0xc00f0002, 0x90000001, /* mov oPts, v1.x */
10479 0x00000001, 0xe00f0000, 0x90e40000, /* mov oT0, v0 */
10480 0x00000001, 0xe00f0001, 0x90e40000, /* mov oT1, v0 */
10481 0x0000ffff
10483 static const DWORD pshader_code[] =
10485 0xffff0101, /* ps_1_1 */
10486 0x00000042, 0xb00f0000, /* tex t0 */
10487 0x00000042, 0xb00f0001, /* tex t1 */
10488 0x00000002, 0x800f0000, 0xb0e40000, 0xb0e40001, /* add r0, t0, t1 */
10489 0x0000ffff
10491 static const DWORD pshader2_code[] =
10493 0xffff0200, /* ps_2_0 */
10494 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
10495 0x0200001f, 0x80000000, 0xb00f0001, /* dcl t1 */
10496 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10497 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10498 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
10499 0x03000042, 0x800f0001, 0xb0e40001, 0xa0e40801, /* texld r1, t1, s1 */
10500 0x03000002, 0x800f0000, 0x80e40000, 0x80e40001, /* add r0, r0, r1 */
10501 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
10502 0x0000ffff
10504 static const DWORD pshader2_zw_code[] =
10506 0xffff0200, /* ps_2_0 */
10507 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
10508 0x0200001f, 0x80000000, 0xb00f0001, /* dcl t1 */
10509 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10510 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10511 0x02000001, 0x80030000, 0xb01b0000, /* mov r0.xy, t0.wzyx */
10512 0x02000001, 0x80030001, 0xb01b0001, /* mov r1.xy, t1.wzyx */
10513 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, /* texld r0, r0, s0 */
10514 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40801, /* texld r1, r1, s1 */
10515 0x03000002, 0x800f0000, 0x80e40000, 0x80e40001, /* add r0, r0, r1 */
10516 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
10517 0x0000ffff
10519 static const DWORD vshader3_code[] =
10521 0xfffe0300, /* vs_3_0 */
10522 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10523 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
10524 0x0200001f, 0x80000005, 0xe00f0001, /* dcl_texcoord0 o1 */
10525 0x0200001f, 0x80010005, 0xe00f0002, /* dcl_texcoord1 o2 */
10526 0x03000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10527 0x04000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10528 0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10529 0x04000004, 0xe00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad o0, v0.w, c3, r0 */
10530 0x02000001, 0xe00f0001, 0x90000000, /* mov o1, v0.x */
10531 0x02000001, 0xe00f0002, 0x90000000, /* mov o2, v0.x */
10532 0x0000ffff
10534 static const DWORD vshader3_psize_code[] =
10536 0xfffe0300, /* vs_3_0 */
10537 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10538 0x0200001f, 0x80000004, 0x90010001, /* dcl_psize v1.x */
10539 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
10540 0x0200001f, 0x80000004, 0xe00f0001, /* dcl_psize o1 */
10541 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
10542 0x0200001f, 0x80010005, 0xe00f0003, /* dcl_texcoord1 o3 */
10543 0x03000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10544 0x04000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10545 0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10546 0x04000004, 0xe00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad o0, v0.w, c3, r0 */
10547 0x02000001, 0xe00f0001, 0x90000001, /* mov o1, v1.x */
10548 0x02000001, 0xe00f0002, 0x90000000, /* mov o2, v0.x */
10549 0x02000001, 0xe00f0003, 0x90000000, /* mov o3, v0.x */
10550 0x0000ffff
10552 static const DWORD pshader3_code[] =
10554 0xffff0300, /* ps_3_0 */
10555 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
10556 0x0200001f, 0x80010005, 0x900f0001, /* dcl_texcoord1 v1 */
10557 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10558 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10559 0x03000042, 0x800f0000, 0x90e40000, 0xa0e40800, /* texld r0, v0, s0 */
10560 0x03000042, 0x800f0001, 0x90e40001, 0xa0e40801, /* texld r1, v1, s1 */
10561 0x03000002, 0x800f0800, 0x80e40000, 0x80e40001, /* add oC0, r0, r1 */
10562 0x0000ffff
10564 static const DWORD pshader3_zw_code[] =
10566 0xffff0300, /* ps_3_0 */
10567 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
10568 0x0200001f, 0x80010005, 0x900f0001, /* dcl_texcoord1 v1 */
10569 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10570 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10571 0x03000042, 0x800f0000, 0x90fe0000, 0xa0e40800, /* texld r0, v0.zw, s0 */
10572 0x03000042, 0x800f0001, 0x90fe0001, 0xa0e40801, /* texld r1, v1.zw, s1 */
10573 0x03000002, 0x800f0800, 0x80e40000, 0x80e40001, /* add oC0, r0, r1 */
10574 0x0000ffff
10576 static const struct test_shader
10578 DWORD version;
10579 const DWORD *code;
10581 novs = {0, NULL},
10582 vs1 = {D3DVS_VERSION(1, 1), vshader_code},
10583 vs1_psize = {D3DVS_VERSION(1, 1), vshader_psize_code},
10584 vs3 = {D3DVS_VERSION(3, 0), vshader3_code},
10585 vs3_psize = {D3DVS_VERSION(3, 0), vshader3_psize_code},
10586 nops = {0, NULL},
10587 ps1 = {D3DPS_VERSION(1, 1), pshader_code},
10588 ps2 = {D3DPS_VERSION(2, 0), pshader2_code},
10589 ps2_zw = {D3DPS_VERSION(2, 0), pshader2_zw_code},
10590 ps3 = {D3DPS_VERSION(3, 0), pshader3_code},
10591 ps3_zw = {D3DVS_VERSION(3, 0), pshader3_zw_code};
10592 static const struct
10594 const struct test_shader *vs;
10595 const struct test_shader *ps;
10596 DWORD accepted_fvf;
10597 unsigned int nonscaled_size, scaled_size;
10598 BOOL gives_0_0_texcoord;
10599 BOOL allow_broken;
10601 test_setups[] =
10603 {&novs, &nops, D3DFVF_XYZ, 32, 45, FALSE, FALSE},
10604 {&vs1, &ps1, D3DFVF_XYZ, 32, 32, FALSE, FALSE},
10605 {&novs, &ps1, D3DFVF_XYZ, 32, 45, FALSE, FALSE},
10606 {&vs1, &nops, D3DFVF_XYZ, 32, 32, FALSE, FALSE},
10607 {&novs, &ps2, D3DFVF_XYZ, 32, 45, FALSE, TRUE},
10608 {&novs, &ps2_zw, D3DFVF_XYZ, 32, 45, TRUE, FALSE},
10609 {&vs1, &ps2, D3DFVF_XYZ, 32, 32, FALSE, TRUE},
10610 {&vs1, &ps2_zw, D3DFVF_XYZ, 32, 32, TRUE, FALSE},
10611 {&vs3, &ps3, D3DFVF_XYZ, 32, 32, FALSE, TRUE},
10612 {&vs3, &ps3_zw, D3DFVF_XYZ, 32, 32, TRUE, FALSE},
10613 {&novs, &nops, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 33, FALSE, FALSE},
10614 {&vs1_psize, &ps1, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 24, FALSE, FALSE},
10615 {&vs3_psize, &ps3, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 24, FALSE, TRUE},
10617 static const struct
10619 BOOL zero_size;
10620 BOOL scale;
10621 BOOL override_min;
10622 DWORD fvf;
10623 const void *vertex_data;
10624 unsigned int vertex_size;
10626 tests[] =
10628 {FALSE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10629 {FALSE, TRUE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10630 {FALSE, FALSE, TRUE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10631 {TRUE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10632 {FALSE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
10633 {FALSE, TRUE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_scaled, sizeof(vertex_pointsize_scaled)},
10634 {FALSE, FALSE, TRUE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
10635 {TRUE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_zero, sizeof(vertex_pointsize_zero)},
10637 /* Transforms the coordinate system [-1.0;1.0]x[1.0;-1.0] to
10638 * [0.0;0.0]x[640.0;480.0]. Z is untouched. */
10639 D3DMATRIX matrix =
10641 2.0f / 640.0f, 0.0f, 0.0f, 0.0f,
10642 0.0f, -2.0f / 480.0f, 0.0f, 0.0f,
10643 0.0f, 0.0f, 1.0f, 0.0f,
10644 -1.0f, 1.0f, 0.0f, 1.0f,
10645 }}};
10647 window = create_window();
10648 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10649 ok(!!d3d, "Failed to create a D3D object.\n");
10650 if (!(device = create_device(d3d, window, window, TRUE)))
10652 skip("Failed to create a D3D device, skipping tests.\n");
10653 goto done;
10656 memset(&caps, 0, sizeof(caps));
10657 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10658 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
10659 if(caps.MaxPointSize < 32.0) {
10660 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
10661 IDirect3DDevice9_Release(device);
10662 goto done;
10665 /* The r500 Windows driver needs a draw with regular texture coordinates at least once during the
10666 * device's lifetime, otherwise texture coordinate generation only works for texture 0. */
10667 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
10668 ok(SUCCEEDED(hr), "Failed to set FVF, hr=%#x.\n", hr);
10669 hr = IDirect3DDevice9_BeginScene(device);
10670 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10671 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, vertices, sizeof(float) * 5);
10672 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10673 hr = IDirect3DDevice9_EndScene(device);
10674 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10676 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10677 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
10678 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10679 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
10680 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
10681 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
10682 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10683 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
10685 hr = IDirect3DDevice9_BeginScene(device);
10686 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10688 ptsize = 15.0f;
10689 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10690 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10691 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
10692 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10694 ptsize = 31.0f;
10695 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10696 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10697 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
10698 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10700 ptsize = 30.75f;
10701 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10702 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10703 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
10704 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10706 if (caps.MaxPointSize >= 63.0f)
10708 ptsize = 63.0f;
10709 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10710 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10711 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
10712 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10714 ptsize = 62.75f;
10715 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10716 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10717 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
10718 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10721 ptsize = 1.0f;
10722 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10723 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10724 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
10725 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10727 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *)&ptsizemax_orig);
10728 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
10729 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *)&ptsizemin_orig);
10730 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
10732 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
10733 ptsize = 15.0f;
10734 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10735 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10736 ptsize = 1.0f;
10737 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsize);
10738 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10739 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
10740 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10742 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsizemax_orig);
10743 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10745 /* pointsize < pointsize_min < pointsize_max?
10746 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
10747 ptsize = 1.0f;
10748 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10749 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10750 ptsize = 15.0f;
10751 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
10752 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10753 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
10754 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10756 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsizemin_orig);
10757 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10759 hr = IDirect3DDevice9_EndScene(device);
10760 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10762 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
10763 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
10764 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
10766 if (caps.MaxPointSize >= 63.0)
10768 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
10769 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
10772 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
10773 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
10774 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
10775 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
10776 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
10778 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10780 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
10781 * generates texture coordinates for the point(result: Yes, it does)
10783 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
10784 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
10785 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
10787 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10788 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
10790 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
10791 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
10792 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
10793 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
10794 memset(&lr, 0, sizeof(lr));
10795 hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
10796 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
10797 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
10798 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
10799 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
10800 memset(&lr, 0, sizeof(lr));
10801 hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
10802 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
10803 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
10804 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
10805 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
10806 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
10807 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
10808 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
10809 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
10810 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10811 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10812 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10813 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10814 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
10815 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10816 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10817 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10818 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
10819 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10821 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
10822 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
10823 ptsize = 32.0;
10824 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
10825 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
10827 hr = IDirect3DDevice9_BeginScene(device);
10828 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10829 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
10830 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10831 hr = IDirect3DDevice9_EndScene(device);
10832 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10834 color = getPixelColor(device, 64-4, 64-4);
10835 ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
10836 color = getPixelColor(device, 64-4, 64+4);
10837 ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
10838 color = getPixelColor(device, 64+4, 64+4);
10839 ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
10840 color = getPixelColor(device, 64+4, 64-4);
10841 ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
10842 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10844 U(matrix).m[0][0] = 1.0f / 64.0f;
10845 U(matrix).m[1][1] = -1.0f / 64.0f;
10846 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
10847 ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
10849 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
10850 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10852 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
10853 D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
10854 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10856 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_A, *(DWORD *)&a);
10857 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
10858 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_B, *(DWORD *)&b);
10859 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
10860 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_C, *(DWORD *)&c);
10861 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
10862 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
10864 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, &S(U(matrix))._11, 4);
10865 ok(SUCCEEDED(hr), "Failed to set vertex shader constants, hr %#x.\n", hr);
10868 if (caps.MaxPointSize < 63.0f)
10870 skip("MaxPointSize %f < 63.0, skipping some tests.\n", caps.MaxPointSize);
10871 goto cleanup;
10874 for (i = 0; i < sizeof(test_setups) / sizeof(test_setups[0]); ++i)
10876 if (caps.VertexShaderVersion < test_setups[i].vs->version
10877 || caps.PixelShaderVersion < test_setups[i].ps->version)
10879 skip("Vertex / pixel shader version not supported, skipping test.\n");
10880 continue;
10882 if (test_setups[i].vs->code)
10884 hr = IDirect3DDevice9_CreateVertexShader(device, test_setups[i].vs->code, &vs);
10885 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
10887 else
10889 vs = NULL;
10891 if (test_setups[i].ps->code)
10893 hr = IDirect3DDevice9_CreatePixelShader(device, test_setups[i].ps->code, &ps);
10894 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
10896 else
10898 ps = NULL;
10901 hr = IDirect3DDevice9_SetVertexShader(device, vs);
10902 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
10903 hr = IDirect3DDevice9_SetPixelShader(device, ps);
10904 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
10906 for (j = 0; j < sizeof(tests) / sizeof(tests[0]); ++j)
10908 BOOL allow_broken = test_setups[i].allow_broken;
10909 unsigned int size = tests[j].override_min ? 63 : tests[j].zero_size ? 0 : tests[j].scale
10910 ? test_setups[i].scaled_size : test_setups[i].nonscaled_size;
10912 if (test_setups[i].accepted_fvf != tests[j].fvf)
10913 continue;
10915 ptsize = tests[j].zero_size ? 0.0f : 32.0f;
10916 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10917 ok(SUCCEEDED(hr), "Failed to set pointsize, hr %#x.\n", hr);
10919 ptsize = tests[j].override_min ? 63.0f : tests[j].zero_size ? 0.0f : ptsizemin_orig;
10920 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
10921 ok(SUCCEEDED(hr), "Failed to set minimum pointsize, hr %#x.\n", hr);
10923 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALEENABLE, tests[j].scale);
10924 ok(SUCCEEDED(hr), "Failed setting point scale state, hr %#x.\n", hr);
10926 hr = IDirect3DDevice9_SetFVF(device, tests[j].fvf);
10927 ok(SUCCEEDED(hr), "Failed setting FVF, hr %#x.\n", hr);
10929 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
10930 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10931 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
10932 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
10934 hr = IDirect3DDevice9_BeginScene(device);
10935 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10936 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1,
10937 tests[j].vertex_data, tests[j].vertex_size);
10938 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10939 hr = IDirect3DDevice9_EndScene(device);
10940 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10942 hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
10943 ok(SUCCEEDED(hr), "Failed to blit, hr %#x.\n", hr);
10944 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10945 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10947 if (tests[j].zero_size)
10949 /* Technically 0 pointsize is undefined in OpenGL but in practice it seems like
10950 * it does the "useful" thing on all the drivers I tried. */
10951 /* On WARP it does draw some pixels, most of the time. */
10952 color = getPixelColor(device, 64, 64);
10953 ok(color_match(color, 0x0000ffff, 0)
10954 || broken(color_match(color, 0x00ff0000, 0))
10955 || broken(color_match(color, 0x00ffff00, 0))
10956 || broken(color_match(color, 0x00000000, 0))
10957 || broken(color_match(color, 0x0000ff00, 0)),
10958 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10960 else
10962 struct surface_readback rb;
10964 get_rt_readback(backbuffer, &rb);
10965 /* On AMD apparently only the first texcoord is modified by the point coordinates
10966 * when using SM2/3 pixel shaders. */
10967 color = get_readback_color(&rb, 64 - size / 2 + 1, 64 - size / 2 + 1);
10968 ok(color_match(color, 0x00ff0000, 0),
10969 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10970 color = get_readback_color(&rb, 64 + size / 2 - 1, 64 - size / 2 + 1);
10971 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x00ffff00, 0)
10972 || (allow_broken && broken(color_match(color, 0x00ff0000, 0))),
10973 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10974 color = get_readback_color(&rb, 64 - size / 2 + 1, 64 + size / 2 - 1);
10975 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x00000000, 0),
10976 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10977 color = get_readback_color(&rb, 64 + size / 2 - 1, 64 + size / 2 - 1);
10978 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x0000ff00, 0)
10979 || (allow_broken && broken(color_match(color, 0x00000000, 0))),
10980 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10982 color = get_readback_color(&rb, 64 - size / 2 - 1, 64 - size / 2 - 1);
10983 ok(color_match(color, 0xff00ffff, 0),
10984 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10985 color = get_readback_color(&rb, 64 + size / 2 + 1, 64 - size / 2 - 1);
10986 ok(color_match(color, 0xff00ffff, 0),
10987 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10988 color = get_readback_color(&rb, 64 - size / 2 - 1, 64 + size / 2 + 1);
10989 ok(color_match(color, 0xff00ffff, 0),
10990 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10991 color = get_readback_color(&rb, 64 + size / 2 + 1, 64 + size / 2 + 1);
10992 ok(color_match(color, 0xff00ffff, 0),
10993 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10995 release_surface_readback(&rb);
10998 IDirect3DDevice9_SetVertexShader(device, NULL);
10999 IDirect3DDevice9_SetPixelShader(device, NULL);
11000 if (vs)
11001 IDirect3DVertexShader9_Release(vs);
11002 if (ps)
11003 IDirect3DVertexShader9_Release(ps);
11006 cleanup:
11007 IDirect3DSurface9_Release(backbuffer);
11008 IDirect3DSurface9_Release(rt);
11010 IDirect3DTexture9_Release(tex1);
11011 IDirect3DTexture9_Release(tex2);
11012 refcount = IDirect3DDevice9_Release(device);
11013 ok(!refcount, "Device has %u references left.\n", refcount);
11014 done:
11015 IDirect3D9_Release(d3d);
11016 DestroyWindow(window);
11019 static void multiple_rendertargets_test(void)
11021 IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
11022 IDirect3DPixelShader9 *ps1, *ps2;
11023 IDirect3DTexture9 *tex1, *tex2;
11024 IDirect3DVertexShader9 *vs;
11025 IDirect3DDevice9 *device;
11026 IDirect3D9 *d3d;
11027 ULONG refcount;
11028 D3DCAPS9 caps;
11029 DWORD color;
11030 HWND window;
11031 HRESULT hr;
11032 UINT i, j;
11034 static const DWORD vshader_code[] =
11036 0xfffe0300, /* vs_3_0 */
11037 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11038 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
11039 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
11040 0x0000ffff /* end */
11042 static const DWORD pshader_code1[] =
11044 0xffff0300, /* ps_3_0 */
11045 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
11046 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
11047 0x0000ffff /* end */
11049 static const DWORD pshader_code2[] =
11051 0xffff0300, /* ps_3_0 */
11052 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
11053 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
11054 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
11055 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
11056 0x0000ffff /* end */
11058 static const float quad[] =
11060 -1.0f, -1.0f, 0.1f,
11061 -1.0f, 1.0f, 0.1f,
11062 1.0f, -1.0f, 0.1f,
11063 1.0f, 1.0f, 0.1f,
11065 static const float texquad[] =
11067 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
11068 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
11069 0.0f, -1.0f, 0.1f, 1.0f, 0.0f,
11070 0.0f, 1.0f, 0.1f, 1.0f, 1.0f,
11072 0.0f, -1.0f, 0.1f, 0.0f, 0.0f,
11073 0.0f, 1.0f, 0.1f, 0.0f, 1.0f,
11074 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
11075 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
11078 window = create_window();
11079 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11080 ok(!!d3d, "Failed to create a D3D object.\n");
11081 if (!(device = create_device(d3d, window, window, TRUE)))
11083 skip("Failed to create a D3D device, skipping tests.\n");
11084 goto done;
11087 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11088 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
11089 if (caps.NumSimultaneousRTs < 2)
11091 skip("Only 1 simultaneous render target supported, skipping MRT test.\n");
11092 IDirect3DDevice9_Release(device);
11093 goto done;
11095 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
11097 skip("No shader model 3 support, skipping tests.\n");
11098 IDirect3DDevice9_Release(device);
11099 goto done;
11102 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
11103 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
11105 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
11106 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
11107 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
11109 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
11110 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
11111 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
11112 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
11113 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
11114 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
11115 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
11116 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
11117 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code1, &ps1);
11118 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
11119 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code2, &ps2);
11120 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
11122 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
11123 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
11124 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
11125 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
11126 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
11127 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
11129 hr = IDirect3DDevice9_SetVertexShader(device, vs);
11130 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
11131 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
11132 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11133 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
11134 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11135 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
11136 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
11138 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
11139 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
11140 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
11141 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11142 color = getPixelColorFromSurface(readback, 8, 8);
11143 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
11144 "Expected color 0x000000ff, got 0x%08x.\n", color);
11145 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
11146 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11147 color = getPixelColorFromSurface(readback, 8, 8);
11148 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
11149 "Expected color 0x000000ff, got 0x%08x.\n", color);
11151 /* Render targets not written by the pixel shader should be unmodified. */
11152 hr = IDirect3DDevice9_SetPixelShader(device, ps1);
11153 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
11154 hr = IDirect3DDevice9_BeginScene(device);
11155 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11156 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
11157 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11158 hr = IDirect3DDevice9_EndScene(device);
11159 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11160 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
11161 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11162 color = getPixelColorFromSurface(readback, 8, 8);
11163 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
11164 "Expected color 0xff00ff00, got 0x%08x.\n", color);
11165 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
11166 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11167 for (i = 6; i < 10; ++i)
11169 for (j = 6; j < 10; ++j)
11171 color = getPixelColorFromSurface(readback, j, i);
11172 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
11173 "Expected color 0xff0000ff, got 0x%08x at %u, %u.\n", color, j, i);
11177 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
11178 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
11179 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
11180 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11181 color = getPixelColorFromSurface(readback, 8, 8);
11182 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
11183 "Expected color 0x0000ff00, got 0x%08x.\n", color);
11184 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
11185 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11186 color = getPixelColorFromSurface(readback, 8, 8);
11187 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
11188 "Expected color 0x0000ff00, got 0x%08x.\n", color);
11190 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
11191 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
11193 hr = IDirect3DDevice9_BeginScene(device);
11194 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11196 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
11197 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11199 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11200 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11201 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11202 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
11203 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11204 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
11205 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
11206 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11207 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
11208 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11209 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11210 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
11212 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
11213 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
11214 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
11215 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11217 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
11218 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
11219 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
11220 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11222 hr = IDirect3DDevice9_EndScene(device);
11223 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11225 color = getPixelColor(device, 160, 240);
11226 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
11227 color = getPixelColor(device, 480, 240);
11228 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
11229 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11231 IDirect3DPixelShader9_Release(ps2);
11232 IDirect3DPixelShader9_Release(ps1);
11233 IDirect3DVertexShader9_Release(vs);
11234 IDirect3DTexture9_Release(tex1);
11235 IDirect3DTexture9_Release(tex2);
11236 IDirect3DSurface9_Release(surf1);
11237 IDirect3DSurface9_Release(surf2);
11238 IDirect3DSurface9_Release(backbuf);
11239 IDirect3DSurface9_Release(readback);
11240 refcount = IDirect3DDevice9_Release(device);
11241 ok(!refcount, "Device has %u references left.\n", refcount);
11242 done:
11243 IDirect3D9_Release(d3d);
11244 DestroyWindow(window);
11247 static void pixelshader_blending_test(void)
11249 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
11250 IDirect3DTexture9 *offscreenTexture = NULL;
11251 IDirect3DDevice9 *device;
11252 IDirect3D9 *d3d;
11253 ULONG refcount;
11254 int fmt_index;
11255 DWORD color;
11256 HWND window;
11257 HRESULT hr;
11259 static const struct
11261 const char *fmtName;
11262 D3DFORMAT textureFormat;
11263 D3DCOLOR resultColorBlending;
11264 D3DCOLOR resultColorNoBlending;
11266 test_formats[] =
11268 {"D3DFMT_G16R16", D3DFMT_G16R16, 0x001820ff, 0x002010ff},
11269 {"D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff},
11270 {"D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001820ff, 0x002010ff},
11271 {"D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00182000, 0x00201000},
11272 {"D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff},
11273 {"D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001820ff, 0x002010ff},
11274 {"D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00182000, 0x00201000},
11275 {"D3DFMT_L8", D3DFMT_L8, 0x00181818, 0x00202020},
11277 static const float quad[][5] =
11279 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
11280 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
11281 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
11282 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
11284 static const struct
11286 struct vec3 position;
11287 DWORD diffuse;
11289 quad1[] =
11291 {{-1.0f, -1.0f, 0.1f}, 0x80103000},
11292 {{-1.0f, 1.0f, 0.1f}, 0x80103000},
11293 {{ 1.0f, -1.0f, 0.1f}, 0x80103000},
11294 {{ 1.0f, 1.0f, 0.1f}, 0x80103000},
11296 quad2[] =
11298 {{-1.0f, -1.0f, 0.1f}, 0x80201000},
11299 {{-1.0f, 1.0f, 0.1f}, 0x80201000},
11300 {{ 1.0f, -1.0f, 0.1f}, 0x80201000},
11301 {{ 1.0f, 1.0f, 0.1f}, 0x80201000},
11304 window = create_window();
11305 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11306 ok(!!d3d, "Failed to create a D3D object.\n");
11307 if (!(device = create_device(d3d, window, window, TRUE)))
11309 skip("Failed to create a D3D device, skipping tests.\n");
11310 goto done;
11313 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
11314 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
11316 for (fmt_index = 0; fmt_index < sizeof(test_formats) / sizeof(*test_formats); ++fmt_index)
11318 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
11320 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11321 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
11323 skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
11324 continue;
11327 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
11328 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
11330 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
11331 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
11332 if(!offscreenTexture) {
11333 continue;
11336 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
11337 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
11338 if(!offscreen) {
11339 continue;
11342 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11343 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
11345 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11346 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11347 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
11348 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11349 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11350 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
11351 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11352 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
11353 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11354 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
11356 /* Below we will draw two quads with different colors and try to blend
11357 * them together. The result color is compared with the expected
11358 * outcome. */
11359 hr = IDirect3DDevice9_BeginScene(device);
11360 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11362 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
11363 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11364 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 1.0f, 0);
11365 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
11367 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
11368 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11370 /* Draw a quad using color 0x0010200. */
11371 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
11372 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11373 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
11374 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11375 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
11376 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11378 /* Draw a quad using color 0x0020100. */
11379 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
11380 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11381 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
11382 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11383 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
11384 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11386 /* We don't want to blend the result on the backbuffer. */
11387 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
11388 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11390 /* Prepare rendering the 'blended' texture quad to the backbuffer. */
11391 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11392 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11393 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)offscreenTexture);
11394 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
11396 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11397 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
11399 /* This time with the texture. */
11400 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
11401 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11403 hr = IDirect3DDevice9_EndScene(device);
11404 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11406 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11407 D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK)
11409 /* Compare the color of the center quad with our expectation. */
11410 color = getPixelColor(device, 320, 240);
11411 ok(color_match(color, test_formats[fmt_index].resultColorBlending, 1),
11412 "Offscreen failed for %s: Got color 0x%08x, expected 0x%08x.\n",
11413 test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
11415 else
11417 /* No pixel shader blending is supported so expect garbage. The
11418 * type of 'garbage' depends on the driver version and OS. E.g. on
11419 * G16R16 ATI reports (on old r9600 drivers) 0x00ffffff and on
11420 * modern ones 0x002010ff which is also what NVIDIA reports. On
11421 * Vista NVIDIA seems to report 0x00ffffff on Geforce7 cards. */
11422 color = getPixelColor(device, 320, 240);
11423 ok((color == 0x00ffffff) || (color == test_formats[fmt_index].resultColorNoBlending),
11424 "Offscreen failed for %s: Got unexpected color 0x%08x, expected no color blending.\n",
11425 test_formats[fmt_index].fmtName, color);
11427 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11429 IDirect3DDevice9_SetTexture(device, 0, NULL);
11430 if(offscreenTexture) {
11431 IDirect3DTexture9_Release(offscreenTexture);
11433 if(offscreen) {
11434 IDirect3DSurface9_Release(offscreen);
11438 IDirect3DSurface9_Release(backbuffer);
11439 refcount = IDirect3DDevice9_Release(device);
11440 ok(!refcount, "Device has %u references left.\n", refcount);
11441 done:
11442 IDirect3D9_Release(d3d);
11443 DestroyWindow(window);
11446 static void tssargtemp_test(void)
11448 IDirect3DDevice9 *device;
11449 IDirect3D9 *d3d;
11450 D3DCOLOR color;
11451 ULONG refcount;
11452 D3DCAPS9 caps;
11453 HWND window;
11454 HRESULT hr;
11456 static const struct
11458 struct vec3 position;
11459 DWORD diffuse;
11461 quad[] =
11463 {{-1.0f, -1.0f, 0.1f}, 0x00ff0000},
11464 {{-1.0f, 1.0f, 0.1f}, 0x00ff0000},
11465 {{ 1.0f, -1.0f, 0.1f}, 0x00ff0000},
11466 {{ 1.0f, 1.0f, 0.1f}, 0x00ff0000},
11469 window = create_window();
11470 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11471 ok(!!d3d, "Failed to create a D3D object.\n");
11472 if (!(device = create_device(d3d, window, window, TRUE)))
11474 skip("Failed to create a D3D device, skipping tests.\n");
11475 goto done;
11478 memset(&caps, 0, sizeof(caps));
11479 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11480 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
11481 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
11482 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
11483 IDirect3DDevice9_Release(device);
11484 goto done;
11487 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
11488 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11490 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11491 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11492 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
11493 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11495 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11496 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11497 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
11498 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11499 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
11500 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11502 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
11503 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11504 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
11505 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11506 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
11507 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11509 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
11510 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11512 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
11513 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
11514 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11515 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
11516 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11517 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
11519 hr = IDirect3DDevice9_BeginScene(device);
11520 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11521 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
11522 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11523 hr = IDirect3DDevice9_EndScene(device);
11524 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11526 color = getPixelColor(device, 320, 240);
11527 ok(color == 0x00ffff00, "TSSARGTEMP test returned color 0x%08x, expected 0x00ffff00\n", color);
11528 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11530 refcount = IDirect3DDevice9_Release(device);
11531 ok(!refcount, "Device has %u references left.\n", refcount);
11532 done:
11533 IDirect3D9_Release(d3d);
11534 DestroyWindow(window);
11537 /* Drawing Indexed Geometry with instances*/
11538 static void stream_test(void)
11540 IDirect3DVertexDeclaration9 *pDecl = NULL;
11541 IDirect3DVertexShader9 *shader = NULL;
11542 IDirect3DVertexBuffer9 *vb3 = NULL;
11543 IDirect3DVertexBuffer9 *vb2 = NULL;
11544 IDirect3DVertexBuffer9 *vb = NULL;
11545 IDirect3DIndexBuffer9 *ib = NULL;
11546 IDirect3DDevice9 *device;
11547 IDirect3D9 *d3d;
11548 ULONG refcount;
11549 D3DCAPS9 caps;
11550 DWORD color;
11551 HWND window;
11552 unsigned i;
11553 HRESULT hr;
11554 BYTE *data;
11555 DWORD ind;
11557 static const struct testdata
11559 DWORD idxVertex; /* number of instances in the first stream */
11560 DWORD idxColor; /* number of instances in the second stream */
11561 DWORD idxInstance; /* should be 1 ?? */
11562 DWORD color1; /* color 1 instance */
11563 DWORD color2; /* color 2 instance */
11564 DWORD color3; /* color 3 instance */
11565 DWORD color4; /* color 4 instance */
11566 WORD strVertex; /* specify which stream to use 0-2*/
11567 WORD strColor;
11568 WORD strInstance;
11570 testcases[]=
11572 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
11573 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
11574 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
11575 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
11576 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 4 */
11577 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
11578 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
11579 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
11580 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 8 */
11581 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 9 */
11582 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 10 */
11583 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 11 */
11584 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 12 */
11585 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 13 */
11586 #if 0
11587 /* This draws one instance on some machines, no instance on others. */
11588 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 14 */
11589 /* This case is handled in a stand alone test,
11590 * SetStreamSourceFreq(0, (D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to
11591 * return D3DERR_INVALIDCALL. */
11592 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0}, /* 15 */
11593 #endif
11595 static const DWORD shader_code[] =
11597 0xfffe0101, /* vs_1_1 */
11598 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11599 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
11600 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
11601 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
11602 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
11603 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
11604 0x0000ffff
11606 static const float quad[][3] =
11608 {-0.5f, -0.5f, 1.1f}, /*0 */
11609 {-0.5f, 0.5f, 1.1f}, /*1 */
11610 { 0.5f, -0.5f, 1.1f}, /*2 */
11611 { 0.5f, 0.5f, 1.1f}, /*3 */
11613 static const float vertcolor[][4] =
11615 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
11616 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
11617 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
11618 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
11620 /* 4 position for 4 instances */
11621 static const float instancepos[][3] =
11623 {-0.6f,-0.6f, 0.0f},
11624 { 0.6f,-0.6f, 0.0f},
11625 { 0.6f, 0.6f, 0.0f},
11626 {-0.6f, 0.6f, 0.0f},
11628 static const short indices[] = {0, 1, 2, 2, 1, 3};
11629 D3DVERTEXELEMENT9 decl[] =
11631 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
11632 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
11633 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
11634 D3DDECL_END()
11637 window = create_window();
11638 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11639 ok(!!d3d, "Failed to create a D3D object.\n");
11640 if (!(device = create_device(d3d, window, window, TRUE)))
11642 skip("Failed to create a D3D device, skipping tests.\n");
11643 goto done;
11646 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11647 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
11648 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
11650 skip("No vs_3_0 support, skipping tests.\n");
11651 IDirect3DDevice9_Release(device);
11652 goto done;
11655 /* set the default value because it isn't done in wine? */
11656 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
11657 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11659 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
11660 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
11661 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11663 /* check wrong cases */
11664 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
11665 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11666 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11667 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11668 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
11669 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11670 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11671 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11672 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
11673 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11674 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11675 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11676 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
11677 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11678 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11679 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11680 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
11681 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11682 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11683 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11685 /* set the default value back */
11686 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
11687 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11689 /* create all VertexBuffers*/
11690 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
11691 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
11692 if(!vb) {
11693 skip("Failed to create a vertex buffer\n");
11694 IDirect3DDevice9_Release(device);
11695 goto done;
11697 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
11698 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
11699 if(!vb2) {
11700 skip("Failed to create a vertex buffer\n");
11701 goto out;
11703 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
11704 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
11705 if(!vb3) {
11706 skip("Failed to create a vertex buffer\n");
11707 goto out;
11710 /* create IndexBuffer*/
11711 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
11712 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
11713 if(!ib) {
11714 skip("Failed to create an index buffer\n");
11715 goto out;
11718 /* copy all Buffers (Vertex + Index)*/
11719 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
11720 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
11721 memcpy(data, quad, sizeof(quad));
11722 hr = IDirect3DVertexBuffer9_Unlock(vb);
11723 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
11724 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
11725 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
11726 memcpy(data, vertcolor, sizeof(vertcolor));
11727 hr = IDirect3DVertexBuffer9_Unlock(vb2);
11728 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
11729 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
11730 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
11731 memcpy(data, instancepos, sizeof(instancepos));
11732 hr = IDirect3DVertexBuffer9_Unlock(vb3);
11733 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
11734 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
11735 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
11736 memcpy(data, indices, sizeof(indices));
11737 hr = IDirect3DIndexBuffer9_Unlock(ib);
11738 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
11740 /* create VertexShader */
11741 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
11742 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
11743 if(!shader) {
11744 skip("Failed to create a vertex shader.\n");
11745 goto out;
11748 hr = IDirect3DDevice9_SetVertexShader(device, shader);
11749 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
11751 hr = IDirect3DDevice9_SetIndices(device, ib);
11752 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
11754 /* run all tests */
11755 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
11757 struct testdata act = testcases[i];
11758 decl[0].Stream = act.strVertex;
11759 decl[1].Stream = act.strColor;
11760 decl[2].Stream = act.strInstance;
11761 /* create VertexDeclarations */
11762 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
11763 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
11765 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
11766 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
11768 hr = IDirect3DDevice9_BeginScene(device);
11769 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11771 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
11772 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
11774 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex,
11775 (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
11776 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11777 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
11778 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11780 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor,
11781 (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
11782 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11783 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
11784 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11786 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance,
11787 (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
11788 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11789 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
11790 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11792 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
11793 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11794 hr = IDirect3DDevice9_EndScene(device);
11795 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11797 /* set all StreamSource && StreamSourceFreq back to default */
11798 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
11799 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11800 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
11801 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11802 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
11803 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11804 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
11805 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11806 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
11807 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11808 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
11809 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11811 hr = IDirect3DVertexDeclaration9_Release(pDecl);
11812 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
11814 color = getPixelColor(device, 160, 360);
11815 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
11816 color = getPixelColor(device, 480, 360);
11817 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
11818 color = getPixelColor(device, 480, 120);
11819 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
11820 color = getPixelColor(device, 160, 120);
11821 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
11823 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11824 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
11827 out:
11828 if(vb) IDirect3DVertexBuffer9_Release(vb);
11829 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
11830 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
11831 if(ib)IDirect3DIndexBuffer9_Release(ib);
11832 if(shader)IDirect3DVertexShader9_Release(shader);
11833 refcount = IDirect3DDevice9_Release(device);
11834 ok(!refcount, "Device has %u references left.\n", refcount);
11835 done:
11836 IDirect3D9_Release(d3d);
11837 DestroyWindow(window);
11840 static void np2_stretch_rect_test(void)
11842 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
11843 IDirect3DTexture9 *dsttex = NULL;
11844 IDirect3DDevice9 *device;
11845 IDirect3D9 *d3d;
11846 D3DCOLOR color;
11847 ULONG refcount;
11848 HWND window;
11849 HRESULT hr;
11851 static const D3DRECT r1 = {0, 0, 50, 50 };
11852 static const D3DRECT r2 = {50, 0, 100, 50 };
11853 static const D3DRECT r3 = {50, 50, 100, 100};
11854 static const D3DRECT r4 = {0, 50, 50, 100};
11855 static const float quad[] =
11857 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
11858 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
11859 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
11860 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
11863 window = create_window();
11864 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11865 ok(!!d3d, "Failed to create a D3D object.\n");
11866 if (!(device = create_device(d3d, window, window, TRUE)))
11868 skip("Failed to create a D3D device, skipping tests.\n");
11869 goto done;
11872 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
11873 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
11875 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
11876 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
11877 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
11878 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
11880 if(!src || !dsttex) {
11881 skip("One or more test resources could not be created\n");
11882 goto cleanup;
11885 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
11886 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
11888 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
11889 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11891 /* Clear the StretchRect destination for debugging */
11892 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
11893 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
11894 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
11895 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11897 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
11898 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
11900 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
11901 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11902 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
11903 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11904 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
11905 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11906 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
11907 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11909 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
11910 * the target -> texture GL blit path
11912 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
11913 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
11914 IDirect3DSurface9_Release(dst);
11916 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11917 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
11919 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
11920 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
11921 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11922 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
11923 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11924 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
11925 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
11926 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
11928 hr = IDirect3DDevice9_BeginScene(device);
11929 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11930 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
11931 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11932 hr = IDirect3DDevice9_EndScene(device);
11933 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11935 color = getPixelColor(device, 160, 360);
11936 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
11937 color = getPixelColor(device, 480, 360);
11938 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
11939 color = getPixelColor(device, 480, 120);
11940 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
11941 color = getPixelColor(device, 160, 120);
11942 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
11943 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11944 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
11946 cleanup:
11947 if(src) IDirect3DSurface9_Release(src);
11948 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
11949 if(dsttex) IDirect3DTexture9_Release(dsttex);
11950 refcount = IDirect3DDevice9_Release(device);
11951 ok(!refcount, "Device has %u references left.\n", refcount);
11952 done:
11953 IDirect3D9_Release(d3d);
11954 DestroyWindow(window);
11957 static void texop_test(void)
11959 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
11960 IDirect3DTexture9 *texture = NULL;
11961 D3DLOCKED_RECT locked_rect;
11962 IDirect3DDevice9 *device;
11963 IDirect3D9 *d3d;
11964 D3DCOLOR color;
11965 ULONG refcount;
11966 D3DCAPS9 caps;
11967 HWND window;
11968 HRESULT hr;
11969 unsigned i;
11971 static const struct {
11972 float x, y, z;
11973 float s, t;
11974 D3DCOLOR diffuse;
11975 } quad[] = {
11976 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
11977 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
11978 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
11979 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
11982 static const D3DVERTEXELEMENT9 decl_elements[] = {
11983 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
11984 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
11985 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
11986 D3DDECL_END()
11989 static const struct {
11990 D3DTEXTUREOP op;
11991 const char *name;
11992 DWORD caps_flag;
11993 D3DCOLOR result;
11994 } test_data[] = {
11995 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
11996 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
11997 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
11998 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
11999 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
12000 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
12001 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
12002 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
12003 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
12004 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
12005 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
12006 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
12007 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
12008 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
12009 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
12010 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
12011 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
12012 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
12013 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
12014 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
12015 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT3", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
12016 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
12017 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
12020 window = create_window();
12021 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12022 ok(!!d3d, "Failed to create a D3D object.\n");
12023 if (!(device = create_device(d3d, window, window, TRUE)))
12025 skip("Failed to create a D3D device, skipping tests.\n");
12026 goto done;
12029 memset(&caps, 0, sizeof(caps));
12030 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12031 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
12033 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
12034 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
12035 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
12036 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
12038 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
12039 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
12040 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
12041 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
12042 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
12043 hr = IDirect3DTexture9_UnlockRect(texture, 0);
12044 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
12045 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
12046 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
12048 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
12049 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12050 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12051 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12052 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12053 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12055 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
12056 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12058 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12059 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12060 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
12061 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12062 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
12063 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12065 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12066 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12068 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
12070 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
12072 skip("tex operation %s not supported\n", test_data[i].name);
12073 continue;
12076 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
12077 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
12079 hr = IDirect3DDevice9_BeginScene(device);
12080 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
12082 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12083 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
12085 hr = IDirect3DDevice9_EndScene(device);
12086 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
12088 color = getPixelColor(device, 320, 240);
12089 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
12090 test_data[i].name, color, test_data[i].result);
12092 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12093 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12096 IDirect3DTexture9_Release(texture);
12097 IDirect3DVertexDeclaration9_Release(vertex_declaration);
12098 refcount = IDirect3DDevice9_Release(device);
12099 ok(!refcount, "Device has %u references left.\n", refcount);
12100 done:
12101 IDirect3D9_Release(d3d);
12102 DestroyWindow(window);
12105 static void yuv_color_test(void)
12107 HRESULT hr;
12108 IDirect3DSurface9 *surface, *target;
12109 unsigned int i;
12110 D3DLOCKED_RECT lr;
12111 IDirect3D9 *d3d;
12112 D3DCOLOR color;
12113 D3DFORMAT skip_once = D3DFMT_UNKNOWN;
12114 IDirect3DDevice9 *device;
12115 D3DSURFACE_DESC desc;
12116 ULONG refcount;
12117 HWND window;
12119 static const struct
12121 DWORD in;
12122 D3DFORMAT format;
12123 const char *fmt_string;
12124 D3DCOLOR left, right;
12126 test_data[] =
12128 {0x00000000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00008700, 0x00008700},
12129 {0xff000000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00008700, 0x004bff1c},
12130 {0x00ff0000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b30000, 0x00b30000},
12131 {0x0000ff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bff1c, 0x00008700},
12132 {0x000000ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000030e1, 0x000030e1},
12133 {0xffff0000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b30000, 0x00ffd01c},
12134 {0xff00ff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bff1c, 0x004bff1c},
12135 {0xff0000ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000030e1, 0x004bffff},
12136 {0x00ffff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffd01c, 0x00b30000},
12137 {0x00ff00ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b300e1, 0x00b300e1},
12138 {0x0000ffff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bffff, 0x001030e1},
12139 {0xffffff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffd01c, 0x00ffd01c},
12140 {0xffff00ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b300e1, 0x00ff79ff},
12141 {0xffffffff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ff79ff, 0x00ff79ff},
12142 {0x4cff4c54, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ff0000, 0x00ff0000},
12143 {0x00800080, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00000000, 0x00000000},
12144 {0xff80ff80, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffffff, 0x00ffffff},
12145 {0x1c6b1cff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000000fd, 0x000000fd},
12147 {0x00000000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00008700, 0x00008700},
12148 {0xff000000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b30000, 0x00b30000},
12149 {0x00ff0000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00008700, 0x004bff1c},
12150 {0x0000ff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000030e1, 0x000030e1},
12151 {0x000000ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bff1c, 0x00008700},
12152 {0xffff0000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b30000, 0x00ffd01c},
12153 {0xff00ff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b300e1, 0x00b300e1},
12154 {0xff0000ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ffd01c, 0x00b30000},
12155 {0x00ffff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000030e1, 0x004bffff},
12156 {0x00ff00ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bff1c, 0x004bff1c},
12157 {0x0000ffff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bffff, 0x000030e1},
12158 {0xffffff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b300e1, 0x00ff79ff},
12159 {0xffff00ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ffd01c, 0x00ffd01c},
12160 {0xffffffff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ff79ff, 0x00ff79ff},
12161 {0x4cff4c54, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000b8b00, 0x00b6ffa3},
12162 {0x00800080, D3DFMT_YUY2, "D3DFMT_YUY2", 0x0000ff00, 0x0000ff00},
12163 {0xff80ff80, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ff00ff, 0x00ff00ff},
12164 {0x1c6b1cff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x006dff45, 0x0000d500},
12167 window = create_window();
12168 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12169 ok(!!d3d, "Failed to create a D3D object.\n");
12170 if (!(device = create_device(d3d, window, window, TRUE)))
12172 skip("Failed to create a D3D device, skipping tests.\n");
12173 goto done;
12176 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
12177 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
12178 hr = IDirect3DSurface9_GetDesc(target, &desc);
12179 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
12181 for (i = 0; i < sizeof(test_data) / sizeof(test_data[0]); i++)
12183 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect.
12184 * Thus use StretchRect to draw the YUV surface onto the screen instead of drawPrimitive. */
12185 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
12186 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, test_data[i].format)))
12188 if (skip_once != test_data[i].format)
12190 skip("%s is not supported.\n", test_data[i].fmt_string);
12191 skip_once = test_data[i].format;
12193 continue;
12195 if (FAILED(IDirect3D9_CheckDeviceFormatConversion(d3d, 0,
12196 D3DDEVTYPE_HAL, test_data[i].format, desc.Format)))
12198 if (skip_once != test_data[i].format)
12200 skip("Driver cannot blit %s surfaces.\n", test_data[i].fmt_string);
12201 skip_once = test_data[i].format;
12203 continue;
12206 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1.
12207 * However, Nvidia Windows drivers have problems with 2x1 YUY2/UYVY surfaces, so use a 4x1 surface and
12208 * fill the second block with dummy data. If the surface has a size of 2x1, those drivers ignore the
12209 * second luminance value, resulting in an incorrect color in the right pixel. */
12210 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 1, test_data[i].format,
12211 D3DPOOL_DEFAULT, &surface, NULL);
12212 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
12215 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
12216 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
12217 ((DWORD *)lr.pBits)[0] = test_data[i].in;
12218 ((DWORD *)lr.pBits)[1] = 0x00800080;
12219 hr = IDirect3DSurface9_UnlockRect(surface);
12220 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
12222 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
12223 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
12224 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
12225 ok(SUCCEEDED(hr), "Failed to draw surface onto backbuffer, hr %#x.\n", hr);
12227 /* Some Windows drivers (mostly Nvidia, but also some VM drivers) insist on doing linear filtering
12228 * although we asked for point filtering. Be careful when reading the results and use the pixel
12229 * centers. In the future we may want to add tests for the filtered pixels as well.
12231 * Unfortunately different implementations(Windows-Nvidia and Mac-AMD tested) interpret some colors
12232 * vastly differently, so we need a max diff of 18. */
12233 color = getPixelColor(device, 1, 240);
12234 ok(color_match(color, test_data[i].left, 18),
12235 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s.\n",
12236 test_data[i].in, color, test_data[i].left, test_data[i].fmt_string);
12237 color = getPixelColor(device, 318, 240);
12238 ok(color_match(color, test_data[i].right, 18),
12239 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s.\n",
12240 test_data[i].in, color, test_data[i].right, test_data[i].fmt_string);
12241 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12242 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
12243 IDirect3DSurface9_Release(surface);
12246 IDirect3DSurface9_Release(target);
12247 refcount = IDirect3DDevice9_Release(device);
12248 ok(!refcount, "Device has %u references left.\n", refcount);
12249 done:
12250 IDirect3D9_Release(d3d);
12251 DestroyWindow(window);
12254 static void yuv_layout_test(void)
12256 HRESULT hr;
12257 IDirect3DSurface9 *surface, *target;
12258 unsigned int fmt, i, x, y;
12259 D3DFORMAT format;
12260 const char *fmt_string;
12261 D3DLOCKED_RECT lr;
12262 IDirect3D9 *d3d;
12263 D3DCOLOR color;
12264 DWORD ref_color;
12265 BYTE *buf, *chroma_buf, *u_buf, *v_buf;
12266 UINT width = 20, height = 16;
12267 IDirect3DDevice9 *device;
12268 ULONG refcount;
12269 D3DCAPS9 caps;
12270 D3DSURFACE_DESC desc;
12271 HWND window;
12273 static const struct
12275 DWORD color1, color2;
12276 DWORD rgb1, rgb2;
12278 test_data[] =
12280 { 0x000000, 0xffffff, 0x00008800, 0x00ff7dff },
12281 { 0xff0000, 0x00ffff, 0x004aff14, 0x00b800ee },
12282 { 0x00ff00, 0xff00ff, 0x000024ee, 0x00ffe114 },
12283 { 0x0000ff, 0xffff00, 0x00b80000, 0x004affff },
12284 { 0xffff00, 0x0000ff, 0x004affff, 0x00b80000 },
12285 { 0xff00ff, 0x00ff00, 0x00ffe114, 0x000024ee },
12286 { 0x00ffff, 0xff0000, 0x00b800ee, 0x004aff14 },
12287 { 0xffffff, 0x000000, 0x00ff7dff, 0x00008800 },
12290 static const struct
12292 D3DFORMAT format;
12293 const char *str;
12295 formats[] =
12297 { D3DFMT_UYVY, "D3DFMT_UYVY", },
12298 { D3DFMT_YUY2, "D3DFMT_YUY2", },
12299 { MAKEFOURCC('Y','V','1','2'), "D3DFMT_YV12", },
12300 { MAKEFOURCC('N','V','1','2'), "D3DFMT_NV12", },
12303 window = create_window();
12304 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12305 ok(!!d3d, "Failed to create a D3D object.\n");
12306 if (!(device = create_device(d3d, window, window, TRUE)))
12308 skip("Failed to create a D3D device, skipping tests.\n");
12309 goto done;
12312 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12313 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
12314 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2
12315 && !(caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL))
12317 skip("No NP2 texture support, skipping YUV texture layout test.\n");
12318 IDirect3DDevice9_Release(device);
12319 goto done;
12322 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
12323 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %#x.\n", hr);
12324 hr = IDirect3DSurface9_GetDesc(target, &desc);
12325 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
12327 for (fmt = 0; fmt < sizeof(formats) / sizeof(formats[0]); fmt++)
12329 format = formats[fmt].format;
12330 fmt_string = formats[fmt].str;
12332 /* Some (all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in
12333 * StretchRect. Thus use StretchRect to draw the YUV surface onto the screen instead
12334 * of drawPrimitive. */
12335 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
12336 D3DRTYPE_SURFACE, format) != D3D_OK)
12338 skip("%s is not supported.\n", fmt_string);
12339 continue;
12341 if (FAILED(IDirect3D9_CheckDeviceFormatConversion(d3d, 0,
12342 D3DDEVTYPE_HAL, format, desc.Format)))
12344 skip("Driver cannot blit %s surfaces.\n", fmt_string);
12345 continue;
12348 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, width, height, format, D3DPOOL_DEFAULT, &surface, NULL);
12349 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %#x.\n", hr);
12351 for (i = 0; i < sizeof(test_data) / sizeof(test_data[0]); i++)
12353 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
12354 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %#x.\n", hr);
12355 buf = lr.pBits;
12356 chroma_buf = buf + lr.Pitch * height;
12357 if (format == MAKEFOURCC('Y','V','1','2'))
12359 v_buf = chroma_buf;
12360 u_buf = chroma_buf + height / 2 * lr.Pitch/2;
12362 /* Draw the top left quarter of the screen with color1, the rest with color2 */
12363 for (y = 0; y < height; y++)
12365 for (x = 0; x < width; x += 2)
12367 DWORD color = (x < width / 2 && y < height / 2) ? test_data[i].color1 : test_data[i].color2;
12368 BYTE Y = (color >> 16) & 0xff;
12369 BYTE U = (color >> 8) & 0xff;
12370 BYTE V = (color >> 0) & 0xff;
12371 if (format == D3DFMT_UYVY)
12373 buf[y * lr.Pitch + 2 * x + 0] = U;
12374 buf[y * lr.Pitch + 2 * x + 1] = Y;
12375 buf[y * lr.Pitch + 2 * x + 2] = V;
12376 buf[y * lr.Pitch + 2 * x + 3] = Y;
12378 else if (format == D3DFMT_YUY2)
12380 buf[y * lr.Pitch + 2 * x + 0] = Y;
12381 buf[y * lr.Pitch + 2 * x + 1] = U;
12382 buf[y * lr.Pitch + 2 * x + 2] = Y;
12383 buf[y * lr.Pitch + 2 * x + 3] = V;
12385 else if (format == MAKEFOURCC('Y','V','1','2'))
12387 buf[y * lr.Pitch + x + 0] = Y;
12388 buf[y * lr.Pitch + x + 1] = Y;
12389 u_buf[(y / 2) * (lr.Pitch / 2) + (x / 2)] = U;
12390 v_buf[(y / 2) * (lr.Pitch / 2) + (x / 2)] = V;
12392 else if (format == MAKEFOURCC('N','V','1','2'))
12394 buf[y * lr.Pitch + x + 0] = Y;
12395 buf[y * lr.Pitch + x + 1] = Y;
12396 chroma_buf[(y / 2) * lr.Pitch + 2 * (x / 2) + 0] = U;
12397 chroma_buf[(y / 2) * lr.Pitch + 2 * (x / 2) + 1] = V;
12401 hr = IDirect3DSurface9_UnlockRect(surface);
12402 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %#x.\n", hr);
12404 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
12405 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %#x.\n", hr);
12406 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
12407 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %#x.\n", hr);
12409 /* Some Windows drivers (mostly Nvidia, but also some VM drivers) insist on doing linear filtering
12410 * although we asked for point filtering. To prevent running into precision problems, read at points
12411 * with some margin within each quadrant.
12413 * Unfortunately different implementations(Windows-Nvidia and Mac-AMD tested) interpret some colors
12414 * vastly differently, so we need a max diff of 18. */
12415 for (y = 0; y < 4; y++)
12417 for (x = 0; x < 4; x++)
12419 UINT xcoord = (1 + 2 * x) * 640 / 8;
12420 UINT ycoord = (1 + 2 * y) * 480 / 8;
12421 ref_color = (y < 2 && x < 2) ? test_data[i].rgb1 : test_data[i].rgb2;
12422 color = getPixelColor(device, xcoord, ycoord);
12423 ok(color_match(color, ref_color, 18),
12424 "Format %s: Got color %#x for pixel (%d/%d)/(%d/%d), pixel %d %d, expected %#x.\n",
12425 fmt_string, color, x, 4, y, 4, xcoord, ycoord, ref_color);
12428 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12430 ok(SUCCEEDED(hr), "Present failed with %#x.\n", hr);
12432 IDirect3DSurface9_Release(surface);
12435 IDirect3DSurface9_Release(target);
12436 refcount = IDirect3DDevice9_Release(device);
12437 ok(!refcount, "Device has %u references left.\n", refcount);
12438 done:
12439 IDirect3D9_Release(d3d);
12440 DestroyWindow(window);
12443 static void texop_range_test(void)
12445 IDirect3DTexture9 *texture;
12446 D3DLOCKED_RECT locked_rect;
12447 IDirect3DDevice9 *device;
12448 IDirect3D9 *d3d;
12449 ULONG refcount;
12450 D3DCAPS9 caps;
12451 DWORD color;
12452 HWND window;
12453 HRESULT hr;
12455 static const struct
12457 float x, y, z;
12458 D3DCOLOR diffuse;
12460 quad[] =
12462 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
12463 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
12464 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
12465 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
12468 window = create_window();
12469 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12470 ok(!!d3d, "Failed to create a D3D object.\n");
12471 if (!(device = create_device(d3d, window, window, TRUE)))
12473 skip("Failed to create a D3D device, skipping tests.\n");
12474 goto done;
12477 /* We need ADD and SUBTRACT operations */
12478 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12479 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
12480 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD))
12482 skip("D3DTOP_ADD is not supported, skipping value range test.\n");
12483 IDirect3DDevice9_Release(device);
12484 goto done;
12486 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT))
12488 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test.\n");
12489 IDirect3DDevice9_Release(device);
12490 goto done;
12493 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12494 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
12495 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12496 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
12497 /* Stage 1: result = diffuse(=1.0) + diffuse
12498 * stage 2: result = result - tfactor(= 0.5)
12500 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12501 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12502 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
12503 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12504 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
12505 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12506 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
12507 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12508 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
12509 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12510 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12511 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12512 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
12513 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12515 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12516 ok(SUCCEEDED(hr), "Failed to clear device, hr %#x.\n\n", hr);
12517 hr = IDirect3DDevice9_BeginScene(device);
12518 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
12519 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12520 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
12521 hr = IDirect3DDevice9_EndScene(device);
12522 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
12524 color = getPixelColor(device, 320, 240);
12525 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
12526 color);
12527 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12528 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12530 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
12531 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
12532 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
12533 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
12534 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
12535 hr = IDirect3DTexture9_UnlockRect(texture, 0);
12536 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
12537 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
12538 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
12540 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
12541 * stage 2: result = result + diffuse(1.0)
12543 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12544 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12545 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12546 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12547 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12548 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12549 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
12550 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12551 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
12552 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12553 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
12554 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12555 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
12556 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12558 hr = IDirect3DDevice9_BeginScene(device);
12559 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
12560 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12561 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
12562 hr = IDirect3DDevice9_EndScene(device);
12563 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
12565 color = getPixelColor(device, 320, 240);
12566 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
12567 color);
12568 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12569 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12571 IDirect3DTexture9_Release(texture);
12572 refcount = IDirect3DDevice9_Release(device);
12573 ok(!refcount, "Device has %u references left.\n", refcount);
12574 done:
12575 IDirect3D9_Release(d3d);
12576 DestroyWindow(window);
12579 static void alphareplicate_test(void)
12581 IDirect3DDevice9 *device;
12582 IDirect3D9 *d3d;
12583 ULONG refcount;
12584 DWORD color;
12585 HWND window;
12586 HRESULT hr;
12588 static const struct
12590 struct vec3 position;
12591 DWORD diffuse;
12593 quad[] =
12595 {{-1.0f, -1.0f, 0.1f}, 0x80ff00ff},
12596 {{-1.0f, 1.0f, 0.1f}, 0x80ff00ff},
12597 {{ 1.0f, -1.0f, 0.1f}, 0x80ff00ff},
12598 {{ 1.0f, 1.0f, 0.1f}, 0x80ff00ff},
12601 window = create_window();
12602 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12603 ok(!!d3d, "Failed to create a D3D object.\n");
12604 if (!(device = create_device(d3d, window, window, TRUE)))
12606 skip("Failed to create a D3D device, skipping tests.\n");
12607 goto done;
12610 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12611 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12613 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12614 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12616 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12617 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12618 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
12619 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12621 hr = IDirect3DDevice9_BeginScene(device);
12622 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12623 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12624 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12625 hr = IDirect3DDevice9_EndScene(device);
12626 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12628 color = getPixelColor(device, 320, 240);
12629 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
12630 color);
12631 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12632 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12634 refcount = IDirect3DDevice9_Release(device);
12635 ok(!refcount, "Device has %u references left.\n", refcount);
12636 done:
12637 IDirect3D9_Release(d3d);
12638 DestroyWindow(window);
12641 static void dp3_alpha_test(void)
12643 IDirect3DDevice9 *device;
12644 IDirect3D9 *d3d;
12645 ULONG refcount;
12646 D3DCAPS9 caps;
12647 DWORD color;
12648 HWND window;
12649 HRESULT hr;
12651 static const struct
12653 struct vec3 position;
12654 DWORD diffuse;
12656 quad[] =
12658 {{-1.0f, -1.0f, 0.1f}, 0x408080c0},
12659 {{-1.0f, 1.0f, 0.1f}, 0x408080c0},
12660 {{ 1.0f, -1.0f, 0.1f}, 0x408080c0},
12661 {{ 1.0f, 1.0f, 0.1f}, 0x408080c0},
12664 window = create_window();
12665 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12666 ok(!!d3d, "Failed to create a D3D object.\n");
12667 if (!(device = create_device(d3d, window, window, TRUE)))
12669 skip("Failed to create a D3D device, skipping tests.\n");
12670 goto done;
12673 memset(&caps, 0, sizeof(caps));
12674 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12675 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
12676 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3))
12678 skip("D3DTOP_DOTPRODUCT3 not supported\n");
12679 IDirect3DDevice9_Release(device);
12680 goto done;
12683 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12684 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12686 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12687 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12689 /* dp3_x4 r0, diffuse_bias, tfactor_bias
12690 * mov r0.a, diffuse.a
12691 * mov r0, r0.a
12693 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
12694 * 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
12695 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
12697 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
12698 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12699 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
12700 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12701 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12702 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12703 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
12704 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12705 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
12706 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12707 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12708 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12709 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
12710 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12711 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
12712 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12713 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
12714 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12715 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12716 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
12718 hr = IDirect3DDevice9_BeginScene(device);
12719 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12720 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12721 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12722 hr = IDirect3DDevice9_EndScene(device);
12723 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12725 color = getPixelColor(device, 320, 240);
12726 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
12727 color);
12728 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12729 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12731 refcount = IDirect3DDevice9_Release(device);
12732 ok(!refcount, "Device has %u references left.\n", refcount);
12733 done:
12734 IDirect3D9_Release(d3d);
12735 DestroyWindow(window);
12738 static void zwriteenable_test(void)
12740 IDirect3DDevice9 *device;
12741 IDirect3D9 *d3d;
12742 D3DCOLOR color;
12743 ULONG refcount;
12744 HWND window;
12745 HRESULT hr;
12747 static const struct
12749 struct vec3 position;
12750 DWORD diffuse;
12752 quad1[] =
12754 {{-1.0f, -1.0f, 0.1f}, 0x00ff0000},
12755 {{-1.0f, 1.0f, 0.1f}, 0x00ff0000},
12756 {{ 1.0f, -1.0f, 0.1f}, 0x00ff0000},
12757 {{ 1.0f, 1.0f, 0.1f}, 0x00ff0000},
12759 quad2[] =
12761 {{-1.0f, -1.0f, 0.9f}, 0x0000ff00},
12762 {{-1.0f, 1.0f, 0.9f}, 0x0000ff00},
12763 {{ 1.0f, -1.0f, 0.9f}, 0x0000ff00},
12764 {{ 1.0f, 1.0f, 0.9f}, 0x0000ff00},
12767 window = create_window();
12768 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12769 ok(!!d3d, "Failed to create a D3D object.\n");
12770 if (!(device = create_device(d3d, window, window, TRUE)))
12772 skip("Failed to create a D3D device, skipping tests.\n");
12773 goto done;
12776 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
12777 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12779 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12780 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12781 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12782 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12783 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12784 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12785 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
12786 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12787 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12788 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
12790 hr = IDirect3DDevice9_BeginScene(device);
12791 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12792 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1,
12793 * zenable = D3DZB_FALSE, zwriteenable = TRUE. The red color is written
12794 * because the z test is disabled. The question is whether the z = 0.1
12795 * values are written into the Z buffer. After the draw, set
12796 * zenable = TRUE and draw a green quad at z = 0.9. If the values are
12797 * written, the z test will fail(0.9 > 0.1) and the red color remains. If
12798 * the values are not written, the z test succeeds(0.9 < 1.0) and the
12799 * green color is written. It turns out that the screen is green, so
12800 * zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z
12801 * buffer. */
12802 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
12803 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12804 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12805 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
12806 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
12807 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12808 hr = IDirect3DDevice9_EndScene(device);
12809 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12811 color = getPixelColor(device, 320, 240);
12812 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
12813 color);
12814 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12815 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12817 refcount = IDirect3DDevice9_Release(device);
12818 ok(!refcount, "Device has %u references left.\n", refcount);
12819 done:
12820 IDirect3D9_Release(d3d);
12821 DestroyWindow(window);
12824 static void alphatest_test(void)
12826 #define ALPHATEST_PASSED 0x0000ff00
12827 #define ALPHATEST_FAILED 0x00ff0000
12828 IDirect3DDevice9 *device;
12829 unsigned int i, j;
12830 IDirect3D9 *d3d;
12831 D3DCOLOR color;
12832 ULONG refcount;
12833 D3DCAPS9 caps;
12834 HWND window;
12835 HRESULT hr;
12837 static const struct
12839 D3DCMPFUNC func;
12840 D3DCOLOR color_less;
12841 D3DCOLOR color_equal;
12842 D3DCOLOR color_greater;
12844 testdata[] =
12846 {D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED},
12847 {D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED},
12848 {D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED},
12849 {D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED},
12850 {D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED},
12851 {D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED},
12852 {D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED},
12853 {D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED},
12855 static const struct
12857 struct vec3 position;
12858 DWORD diffuse;
12860 quad[] =
12862 {{-1.0f, -1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
12863 {{-1.0f, 1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
12864 {{ 1.0f, -1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
12865 {{ 1.0f, 1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
12868 window = create_window();
12869 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12870 ok(!!d3d, "Failed to create a D3D object.\n");
12871 if (!(device = create_device(d3d, window, window, TRUE)))
12873 skip("Failed to create a D3D device, skipping tests.\n");
12874 goto done;
12877 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
12878 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
12880 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12881 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
12882 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
12883 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12884 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12885 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12887 for (j = 0; j < 2; ++j)
12889 if (j == 1)
12891 /* Try a pixel shader instead of fixed function. The wined3d code
12892 * may emulate the alpha test either for performance reasons
12893 * (floating point RTs) or to work around driver bugs (GeForce
12894 * 7x00 cards on MacOS). There may be a different codepath for ffp
12895 * and shader in this case, and the test should cover both. */
12896 IDirect3DPixelShader9 *ps;
12897 static const DWORD shader_code[] =
12899 0xffff0101, /* ps_1_1 */
12900 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
12901 0x0000ffff /* end */
12903 memset(&caps, 0, sizeof(caps));
12904 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12905 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
12906 if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
12907 break;
12910 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
12911 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
12912 hr = IDirect3DDevice9_SetPixelShader(device, ps);
12913 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
12914 IDirect3DPixelShader9_Release(ps);
12917 for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
12918 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
12919 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12921 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
12922 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12923 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
12924 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12925 hr = IDirect3DDevice9_BeginScene(device);
12926 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12927 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12928 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12929 hr = IDirect3DDevice9_EndScene(device);
12930 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12931 color = getPixelColor(device, 320, 240);
12932 ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
12933 color, testdata[i].color_less, testdata[i].func);
12934 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12935 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12937 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
12938 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12939 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
12940 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12941 hr = IDirect3DDevice9_BeginScene(device);
12942 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12943 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12944 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12945 hr = IDirect3DDevice9_EndScene(device);
12946 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12947 color = getPixelColor(device, 320, 240);
12948 ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
12949 color, testdata[i].color_equal, testdata[i].func);
12950 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12951 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12953 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
12954 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12955 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
12956 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12957 hr = IDirect3DDevice9_BeginScene(device);
12958 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12959 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12960 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12961 hr = IDirect3DDevice9_EndScene(device);
12962 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12963 color = getPixelColor(device, 320, 240);
12964 ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
12965 color, testdata[i].color_greater, testdata[i].func);
12966 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12967 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12971 refcount = IDirect3DDevice9_Release(device);
12972 ok(!refcount, "Device has %u references left.\n", refcount);
12973 done:
12974 IDirect3D9_Release(d3d);
12975 DestroyWindow(window);
12978 static void sincos_test(void)
12980 IDirect3DVertexShader9 *sin_shader, *cos_shader;
12981 IDirect3DDevice9 *device;
12982 struct vec3 data[1280];
12983 IDirect3D9 *d3d;
12984 unsigned int i;
12985 ULONG refcount;
12986 D3DCAPS9 caps;
12987 HWND window;
12988 HRESULT hr;
12990 static const DWORD sin_shader_code[] =
12992 0xfffe0200, /* vs_2_0 */
12993 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
12994 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
12995 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
12996 0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.y, r1.x, c0, c1 */
12997 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
12998 0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002, /* mul oPos.y, r0.y, c2.w */
12999 0x02000001, 0xd00f0000, 0xa0a60002, /* mov oD0, c2.zyzz */
13000 0x0000ffff /* end */
13002 static const DWORD cos_shader_code[] =
13004 0xfffe0200, /* vs_2_0 */
13005 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
13006 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
13007 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
13008 0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.x, r1.x, c0, c1 */
13009 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
13010 0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002, /* mul oPos.y, r0.x, c2.w */
13011 0x02000001, 0xd00f0000, 0xa0a90002, /* mov oD0, c2.yzzz */
13012 0x0000ffff /* end */
13014 static const float sincosc1[4] = {D3DSINCOSCONST1};
13015 static const float sincosc2[4] = {D3DSINCOSCONST2};
13017 window = create_window();
13018 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13019 ok(!!d3d, "Failed to create a D3D object.\n");
13020 if (!(device = create_device(d3d, window, window, TRUE)))
13022 skip("Failed to create a D3D device, skipping tests.\n");
13023 goto done;
13026 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13027 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13028 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
13030 skip("No vs_2_0 support, skipping tests.\n");
13031 IDirect3DDevice9_Release(device);
13032 goto done;
13035 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
13036 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
13038 hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
13039 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
13040 hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
13041 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
13042 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13043 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
13044 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
13045 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
13046 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
13047 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
13049 /* Generate a point from -1 to 1 every 0.5 pixels */
13050 for(i = 0; i < 1280; i++) {
13051 data[i].x = (-640.0 + i) / 640.0;
13052 data[i].y = 0.0;
13053 data[i].z = 0.1;
13056 hr = IDirect3DDevice9_BeginScene(device);
13057 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13059 hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
13060 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
13061 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
13062 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13064 hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
13065 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
13066 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
13067 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13069 hr = IDirect3DDevice9_EndScene(device);
13070 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13072 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13073 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
13074 /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
13076 IDirect3DVertexShader9_Release(sin_shader);
13077 IDirect3DVertexShader9_Release(cos_shader);
13078 refcount = IDirect3DDevice9_Release(device);
13079 ok(!refcount, "Device has %u references left.\n", refcount);
13080 done:
13081 IDirect3D9_Release(d3d);
13082 DestroyWindow(window);
13085 static void loop_index_test(void)
13087 IDirect3DVertexShader9 *shader;
13088 IDirect3DDevice9 *device;
13089 IDirect3D9 *d3d;
13090 float values[4];
13091 ULONG refcount;
13092 D3DCAPS9 caps;
13093 DWORD color;
13094 HWND window;
13095 HRESULT hr;
13097 static const DWORD shader_code[] =
13099 0xfffe0200, /* vs_2_0 */
13100 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
13101 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
13102 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
13103 0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1] */
13104 0x0000001d, /* endloop */
13105 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
13106 0x02000001, 0xd00f0000, 0x80e40000, /* mov oD0, r0 */
13107 0x0000ffff /* END */
13109 static const float quad[] =
13111 -1.0f, -1.0f, 0.1f,
13112 -1.0f, 1.0f, 0.1f,
13113 1.0f, -1.0f, 0.1f,
13114 1.0f, 1.0f, 0.1f,
13116 static const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
13117 static const float one[4] = {1.0f, 1.0f, 1.0f, 1.0f};
13118 static const int i0[4] = {2, 10, -3, 0};
13120 window = create_window();
13121 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13122 ok(!!d3d, "Failed to create a D3D object.\n");
13123 if (!(device = create_device(d3d, window, window, TRUE)))
13125 skip("Failed to create a D3D device, skipping tests.\n");
13126 goto done;
13129 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13130 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13131 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
13133 skip("No vs_2_0 support, skipping tests.\n");
13134 IDirect3DDevice9_Release(device);
13135 goto done;
13138 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
13139 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
13140 hr = IDirect3DDevice9_SetVertexShader(device, shader);
13141 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
13142 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13143 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
13144 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
13145 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
13147 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
13148 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13149 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
13150 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13151 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
13152 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13153 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
13154 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13155 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
13156 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13157 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
13158 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13159 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
13160 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13161 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
13162 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13163 values[0] = 1.0;
13164 values[1] = 1.0;
13165 values[2] = 0.0;
13166 values[3] = 0.0;
13167 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
13168 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13169 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
13170 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13171 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
13172 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13173 values[0] = -1.0;
13174 values[1] = 0.0;
13175 values[2] = 0.0;
13176 values[3] = 0.0;
13177 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
13178 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13179 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
13180 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13181 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
13182 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13183 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
13184 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13185 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
13186 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13188 hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
13189 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
13191 hr = IDirect3DDevice9_BeginScene(device);
13192 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13193 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
13194 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13195 hr = IDirect3DDevice9_EndScene(device);
13196 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13197 color = getPixelColor(device, 320, 240);
13198 ok(color_match(color, 0x0000ff00, 1),
13199 "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
13200 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13201 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
13203 IDirect3DVertexShader9_Release(shader);
13204 refcount = IDirect3DDevice9_Release(device);
13205 ok(!refcount, "Device has %u references left.\n", refcount);
13206 done:
13207 IDirect3D9_Release(d3d);
13208 DestroyWindow(window);
13211 static void sgn_test(void)
13213 IDirect3DVertexShader9 *shader;
13214 IDirect3DDevice9 *device;
13215 IDirect3D9 *d3d;
13216 ULONG refcount;
13217 D3DCAPS9 caps;
13218 DWORD color;
13219 HWND window;
13220 HRESULT hr;
13222 static const DWORD shader_code[] =
13224 0xfffe0200, /* vs_2_0 */
13225 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position o0 */
13226 0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
13227 0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0 */
13228 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
13229 0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002, /* sgn r0, c0, r1, r2 */
13230 0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001, /* add oD0, r0, c1 */
13231 0x0000ffff /* end */
13233 static const float quad[] =
13235 -1.0f, -1.0f, 0.1f,
13236 -1.0f, 1.0f, 0.1f,
13237 1.0f, -1.0f, 0.1f,
13238 1.0f, 1.0f, 0.1f,
13241 window = create_window();
13242 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13243 ok(!!d3d, "Failed to create a D3D object.\n");
13244 if (!(device = create_device(d3d, window, window, TRUE)))
13246 skip("Failed to create a D3D device, skipping tests.\n");
13247 goto done;
13250 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13251 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13252 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
13254 skip("No vs_2_0 support, skipping tests.\n");
13255 IDirect3DDevice9_Release(device);
13256 goto done;
13259 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
13260 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
13261 hr = IDirect3DDevice9_SetVertexShader(device, shader);
13262 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
13263 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13264 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
13265 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
13266 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
13268 hr = IDirect3DDevice9_BeginScene(device);
13269 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13270 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
13271 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13272 hr = IDirect3DDevice9_EndScene(device);
13273 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13274 color = getPixelColor(device, 320, 240);
13275 ok(color_match(color, 0x008000ff, 1),
13276 "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
13277 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13278 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
13280 IDirect3DVertexShader9_Release(shader);
13281 refcount = IDirect3DDevice9_Release(device);
13282 ok(!refcount, "Device has %u references left.\n", refcount);
13283 done:
13284 IDirect3D9_Release(d3d);
13285 DestroyWindow(window);
13288 static void viewport_test(void)
13290 IDirect3DDevice9 *device;
13291 BOOL draw_failed = TRUE;
13292 D3DVIEWPORT9 vp;
13293 IDirect3D9 *d3d;
13294 ULONG refcount;
13295 DWORD color;
13296 HWND window;
13297 HRESULT hr;
13299 static const float quad[] =
13301 -0.5f, -0.5f, 0.1f,
13302 -0.5f, 0.5f, 0.1f,
13303 0.5f, -0.5f, 0.1f,
13304 0.5f, 0.5f, 0.1f,
13307 window = create_window();
13308 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13309 ok(!!d3d, "Failed to create a D3D object.\n");
13310 if (!(device = create_device(d3d, window, window, TRUE)))
13312 skip("Failed to create a D3D device, skipping tests.\n");
13313 goto done;
13316 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
13317 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
13319 /* Test a viewport with Width and Height bigger than the surface dimensions
13321 * TODO: Test Width < surface.width, but X + Width > surface.width
13322 * TODO: Test Width < surface.width, what happens with the height?
13324 * The expected behavior is that the viewport behaves like the "default"
13325 * viewport with X = Y = 0, Width = surface_width, Height = surface_height,
13326 * MinZ = 0.0, MaxZ = 1.0.
13328 * Starting with Windows 7 the behavior among driver versions is not
13329 * consistent. The SetViewport call is accepted on all drivers. Some
13330 * drivers(older nvidia ones) refuse to draw and return an error. Newer
13331 * nvidia drivers draw, but use the actual values in the viewport and only
13332 * display the upper left part on the surface.
13334 memset(&vp, 0, sizeof(vp));
13335 vp.X = 0;
13336 vp.Y = 0;
13337 vp.Width = 10000;
13338 vp.Height = 10000;
13339 vp.MinZ = 0.0;
13340 vp.MaxZ = 0.0;
13341 hr = IDirect3DDevice9_SetViewport(device, &vp);
13342 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
13344 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13345 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
13347 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13348 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
13349 hr = IDirect3DDevice9_BeginScene(device);
13350 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13351 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
13352 ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
13353 draw_failed = FAILED(hr);
13354 hr = IDirect3DDevice9_EndScene(device);
13355 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13357 if(!draw_failed)
13359 color = getPixelColor(device, 158, 118);
13360 ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
13361 color = getPixelColor(device, 162, 118);
13362 ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
13363 color = getPixelColor(device, 158, 122);
13364 ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
13365 color = getPixelColor(device, 162, 122);
13366 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (162,122) has color %08x\n", color);
13368 color = getPixelColor(device, 478, 358);
13369 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (478,358 has color %08x\n", color);
13370 color = getPixelColor(device, 482, 358);
13371 ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
13372 color = getPixelColor(device, 478, 362);
13373 ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
13374 color = getPixelColor(device, 482, 362);
13375 ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
13378 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13379 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
13381 refcount = IDirect3DDevice9_Release(device);
13382 ok(!refcount, "Device has %u references left.\n", refcount);
13383 done:
13384 IDirect3D9_Release(d3d);
13385 DestroyWindow(window);
13388 /* This test tests depth clamping / clipping behaviour:
13389 * - With software vertex processing, depth values are clamped to the
13390 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
13391 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
13392 * same as regular vertices here.
13393 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
13394 * Normal vertices are always clipped. Pretransformed vertices are
13395 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
13396 * - The viewport's MinZ/MaxZ is irrelevant for this.
13398 static void depth_clamp_test(void)
13400 IDirect3DDevice9 *device;
13401 D3DVIEWPORT9 vp;
13402 IDirect3D9 *d3d;
13403 D3DCOLOR color;
13404 ULONG refcount;
13405 D3DCAPS9 caps;
13406 HWND window;
13407 HRESULT hr;
13409 static const struct
13411 struct vec4 position;
13412 DWORD diffuse;
13414 quad1[] =
13416 {{ 0.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
13417 {{640.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
13418 {{ 0.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
13419 {{640.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
13421 quad2[] =
13423 {{ 0.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
13424 {{640.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
13425 {{ 0.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
13426 {{640.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
13428 quad3[] =
13430 {{112.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
13431 {{208.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
13432 {{112.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
13433 {{208.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
13435 quad4[] =
13437 {{ 42.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
13438 {{112.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
13439 {{ 42.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
13440 {{112.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
13442 static const struct
13444 struct vec3 position;
13445 DWORD diffuse;
13447 quad5[] =
13449 {{-0.5f, 0.5f, 10.0f}, 0xff14f914},
13450 {{ 0.5f, 0.5f, 10.0f}, 0xff14f914},
13451 {{-0.5f, -0.5f, 10.0f}, 0xff14f914},
13452 {{ 0.5f, -0.5f, 10.0f}, 0xff14f914},
13454 quad6[] =
13456 {{-1.0f, 0.5f, 10.0f}, 0xfff91414},
13457 {{ 1.0f, 0.5f, 10.0f}, 0xfff91414},
13458 {{-1.0f, 0.25f, 10.0f}, 0xfff91414},
13459 {{ 1.0f, 0.25f, 10.0f}, 0xfff91414},
13462 window = create_window();
13463 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13464 ok(!!d3d, "Failed to create a D3D object.\n");
13465 if (!(device = create_device(d3d, window, window, TRUE)))
13467 skip("Failed to create a D3D device, skipping tests.\n");
13468 goto done;
13471 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13472 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13474 vp.X = 0;
13475 vp.Y = 0;
13476 vp.Width = 640;
13477 vp.Height = 480;
13478 vp.MinZ = 0.0;
13479 vp.MaxZ = 7.5;
13481 hr = IDirect3DDevice9_SetViewport(device, &vp);
13482 if(FAILED(hr))
13484 /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
13485 * the tests because the 7.5 is just intended to show that it doesn't have
13486 * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
13487 * viewport and continue.
13489 ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
13490 vp.MaxZ = 1.0;
13491 hr = IDirect3DDevice9_SetViewport(device, &vp);
13493 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
13495 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
13496 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13498 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
13499 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13500 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13501 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13502 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13503 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13504 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13505 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13507 hr = IDirect3DDevice9_BeginScene(device);
13508 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13510 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
13511 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13513 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13514 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13515 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13516 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13518 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
13519 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13521 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
13522 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13523 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
13524 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13526 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
13527 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13529 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13530 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13532 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
13533 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13535 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
13536 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13538 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
13539 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13541 hr = IDirect3DDevice9_EndScene(device);
13542 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13544 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
13546 color = getPixelColor(device, 75, 75);
13547 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13548 color = getPixelColor(device, 150, 150);
13549 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13550 color = getPixelColor(device, 320, 240);
13551 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13552 color = getPixelColor(device, 320, 330);
13553 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13554 color = getPixelColor(device, 320, 330);
13555 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13557 else
13559 color = getPixelColor(device, 75, 75);
13560 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
13561 color = getPixelColor(device, 150, 150);
13562 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
13563 color = getPixelColor(device, 320, 240);
13564 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
13565 color = getPixelColor(device, 320, 330);
13566 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13567 color = getPixelColor(device, 320, 330);
13568 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13571 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13572 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13574 refcount = IDirect3DDevice9_Release(device);
13575 ok(!refcount, "Device has %u references left.\n", refcount);
13576 done:
13577 IDirect3D9_Release(d3d);
13578 DestroyWindow(window);
13581 static void depth_bounds_test(void)
13583 static const struct
13585 struct vec4 position;
13586 DWORD diffuse;
13588 quad1[] =
13590 {{ 0.0f, 0.0f, 0.0f, 1.0f}, 0xfff9e814},
13591 {{640.0f, 0.0f, 0.0f, 1.0f}, 0xfff9e814},
13592 {{ 0.0f, 480.0f, 1.0f, 1.0f}, 0xfff9e814},
13593 {{640.0f, 480.0f, 1.0f, 1.0f}, 0xfff9e814},
13595 quad2[] =
13597 {{ 0.0f, 0.0f, 0.6f, 1.0f}, 0xff002b7f},
13598 {{640.0f, 0.0f, 0.6f, 1.0f}, 0xff002b7f},
13599 {{ 0.0f, 480.0f, 0.6f, 1.0f}, 0xff002b7f},
13600 {{640.0f, 480.0f, 0.6f, 1.0f}, 0xff002b7f},
13602 quad3[] =
13604 {{ 0.0f, 100.0f, 0.6f, 1.0f}, 0xfff91414},
13605 {{640.0f, 100.0f, 0.6f, 1.0f}, 0xfff91414},
13606 {{ 0.0f, 160.0f, 0.6f, 1.0f}, 0xfff91414},
13607 {{640.0f, 160.0f, 0.6f, 1.0f}, 0xfff91414},
13610 union {
13611 DWORD d;
13612 float f;
13613 } tmpvalue;
13615 IDirect3DSurface9 *offscreen_surface = NULL;
13616 IDirect3DDevice9 *device;
13617 IDirect3D9 *d3d;
13618 D3DCOLOR color;
13619 ULONG refcount;
13620 HWND window;
13621 HRESULT hr;
13623 window = create_window();
13624 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13625 ok(!!d3d, "Failed to create a D3D object.\n");
13626 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
13627 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK)
13629 skip("No NVDB (depth bounds test) support, skipping tests.\n");
13630 goto done;
13632 if (!(device = create_device(d3d, window, window, TRUE)))
13634 skip("Failed to create a D3D device, skipping tests.\n");
13635 goto done;
13638 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
13639 MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
13640 ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
13641 if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
13643 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
13644 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13646 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13647 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13648 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13649 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13650 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13651 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13652 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13653 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13656 hr = IDirect3DDevice9_BeginScene(device);
13657 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13659 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
13660 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13662 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13663 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13665 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
13666 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13668 tmpvalue.f = 0.625;
13669 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
13670 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13672 tmpvalue.f = 0.75;
13673 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
13674 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13676 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13677 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13679 tmpvalue.f = 0.75;
13680 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
13681 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13683 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
13684 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13686 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
13687 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13689 hr = IDirect3DDevice9_EndScene(device);
13690 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13692 color = getPixelColor(device, 150, 130);
13693 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13694 color = getPixelColor(device, 150, 200);
13695 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13696 color = getPixelColor(device, 150, 300-5);
13697 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13698 color = getPixelColor(device, 150, 300+5);
13699 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
13700 color = getPixelColor(device, 150, 330);
13701 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
13702 color = getPixelColor(device, 150, 360-5);
13703 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
13704 color = getPixelColor(device, 150, 360+5);
13705 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13707 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13708 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13709 refcount = IDirect3DDevice9_Release(device);
13710 ok(!refcount, "Device has %u references left.\n", refcount);
13711 done:
13712 IDirect3D9_Release(d3d);
13713 DestroyWindow(window);
13716 static void depth_buffer_test(void)
13718 static const struct
13720 struct vec3 position;
13721 DWORD diffuse;
13723 quad1[] =
13725 {{-1.0, 1.0, 0.33f}, 0xff00ff00},
13726 {{ 1.0, 1.0, 0.33f}, 0xff00ff00},
13727 {{-1.0, -1.0, 0.33f}, 0xff00ff00},
13728 {{ 1.0, -1.0, 0.33f}, 0xff00ff00},
13730 quad2[] =
13732 {{-1.0, 1.0, 0.50f}, 0xffff00ff},
13733 {{ 1.0, 1.0, 0.50f}, 0xffff00ff},
13734 {{-1.0, -1.0, 0.50f}, 0xffff00ff},
13735 {{ 1.0, -1.0, 0.50f}, 0xffff00ff},
13737 quad3[] =
13739 {{-1.0, 1.0, 0.66f}, 0xffff0000},
13740 {{ 1.0, 1.0, 0.66f}, 0xffff0000},
13741 {{-1.0, -1.0, 0.66f}, 0xffff0000},
13742 {{ 1.0, -1.0, 0.66f}, 0xffff0000},
13744 static const DWORD expected_colors[4][4] =
13746 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
13747 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
13748 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
13749 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
13752 IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
13753 IDirect3DDevice9 *device;
13754 unsigned int i, j;
13755 D3DVIEWPORT9 vp;
13756 IDirect3D9 *d3d;
13757 D3DCOLOR color;
13758 ULONG refcount;
13759 HWND window;
13760 HRESULT hr;
13762 window = create_window();
13763 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13764 ok(!!d3d, "Failed to create a D3D object.\n");
13765 if (!(device = create_device(d3d, window, window, TRUE)))
13767 skip("Failed to create a D3D device, skipping tests.\n");
13768 goto done;
13771 vp.X = 0;
13772 vp.Y = 0;
13773 vp.Width = 640;
13774 vp.Height = 480;
13775 vp.MinZ = 0.0;
13776 vp.MaxZ = 1.0;
13778 hr = IDirect3DDevice9_SetViewport(device, &vp);
13779 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
13781 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13782 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13783 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13784 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13785 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13786 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13787 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13788 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13789 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13790 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13792 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
13793 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
13794 hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
13795 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
13796 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13797 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
13798 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
13799 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13800 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13801 D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
13802 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13804 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
13805 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13806 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
13807 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13809 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
13810 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13811 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
13812 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13814 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
13815 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13816 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
13817 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13819 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
13820 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13821 hr = IDirect3DDevice9_BeginScene(device);
13822 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13823 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13824 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13825 hr = IDirect3DDevice9_EndScene(device);
13826 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13828 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
13829 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13831 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13832 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13834 hr = IDirect3DDevice9_BeginScene(device);
13835 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13836 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13837 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13838 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
13839 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13840 hr = IDirect3DDevice9_EndScene(device);
13841 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13843 for (i = 0; i < 4; ++i)
13845 for (j = 0; j < 4; ++j)
13847 unsigned int x = 80 * ((2 * j) + 1);
13848 unsigned int y = 60 * ((2 * i) + 1);
13849 color = getPixelColor(device, x, y);
13850 ok(color_match(color, expected_colors[i][j], 0),
13851 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
13855 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13856 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13858 IDirect3DSurface9_Release(backbuffer);
13859 IDirect3DSurface9_Release(rt3);
13860 IDirect3DSurface9_Release(rt2);
13861 IDirect3DSurface9_Release(rt1);
13862 refcount = IDirect3DDevice9_Release(device);
13863 ok(!refcount, "Device has %u references left.\n", refcount);
13864 done:
13865 IDirect3D9_Release(d3d);
13866 DestroyWindow(window);
13869 /* Test that partial depth copies work the way they're supposed to. The clear
13870 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
13871 * the following draw should only copy back the part that was modified. */
13872 static void depth_buffer2_test(void)
13874 static const struct
13876 struct vec3 position;
13877 DWORD diffuse;
13879 quad[] =
13881 {{-1.0f, 1.0f, 0.66f}, 0xffff0000},
13882 {{ 1.0f, 1.0f, 0.66f}, 0xffff0000},
13883 {{-1.0f, -1.0f, 0.66f}, 0xffff0000},
13884 {{ 1.0f, -1.0f, 0.66f}, 0xffff0000},
13887 IDirect3DSurface9 *backbuffer, *rt1, *rt2;
13888 IDirect3DDevice9 *device;
13889 unsigned int i, j;
13890 D3DVIEWPORT9 vp;
13891 IDirect3D9 *d3d;
13892 D3DCOLOR color;
13893 ULONG refcount;
13894 HWND window;
13895 HRESULT hr;
13897 window = create_window();
13898 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13899 ok(!!d3d, "Failed to create a D3D object.\n");
13900 if (!(device = create_device(d3d, window, window, TRUE)))
13902 skip("Failed to create a D3D device, skipping tests.\n");
13903 goto done;
13906 vp.X = 0;
13907 vp.Y = 0;
13908 vp.Width = 640;
13909 vp.Height = 480;
13910 vp.MinZ = 0.0;
13911 vp.MaxZ = 1.0;
13913 hr = IDirect3DDevice9_SetViewport(device, &vp);
13914 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
13916 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13917 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13918 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13919 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13920 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13921 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13922 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13923 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13924 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13925 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13927 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13928 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
13929 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13930 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
13931 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
13932 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13933 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
13934 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
13936 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
13937 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13938 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
13939 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13941 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
13942 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13943 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
13944 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13946 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
13947 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13948 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
13949 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13951 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
13952 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13954 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13955 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13957 hr = IDirect3DDevice9_BeginScene(device);
13958 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13959 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13960 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13961 hr = IDirect3DDevice9_EndScene(device);
13962 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13964 for (i = 0; i < 4; ++i)
13966 for (j = 0; j < 4; ++j)
13968 unsigned int x = 80 * ((2 * j) + 1);
13969 unsigned int y = 60 * ((2 * i) + 1);
13970 color = getPixelColor(device, x, y);
13971 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
13972 "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
13976 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13977 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13979 IDirect3DSurface9_Release(backbuffer);
13980 IDirect3DSurface9_Release(rt2);
13981 IDirect3DSurface9_Release(rt1);
13982 refcount = IDirect3DDevice9_Release(device);
13983 ok(!refcount, "Device has %u references left.\n", refcount);
13984 done:
13985 IDirect3D9_Release(d3d);
13986 DestroyWindow(window);
13989 static void depth_blit_test(void)
13991 static const struct
13993 struct vec3 position;
13994 DWORD diffuse;
13996 quad1[] =
13998 {{-1.0f, 1.0f, 0.33f}, 0xff00ff00},
13999 {{ 1.0f, 1.0f, 0.33f}, 0xff00ff00},
14000 {{-1.0f, -1.0f, 0.33f}, 0xff00ff00},
14001 {{ 1.0f, -1.0f, 0.33f}, 0xff00ff00},
14003 quad2[] =
14005 {{-1.0f, 1.0f, 0.66f}, 0xff0000ff},
14006 {{ 1.0f, 1.0f, 0.66f}, 0xff0000ff},
14007 {{-1.0f, -1.0f, 0.66f}, 0xff0000ff},
14008 {{ 1.0f, -1.0f, 0.66f}, 0xff0000ff},
14010 static const DWORD expected_colors[4][4] =
14012 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
14013 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
14014 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
14015 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
14018 IDirect3DSurface9 *backbuffer, *ds1, *ds2, *ds3;
14019 IDirect3DDevice9 *device;
14020 RECT src_rect, dst_rect;
14021 unsigned int i, j;
14022 D3DVIEWPORT9 vp;
14023 IDirect3D9 *d3d;
14024 D3DCOLOR color;
14025 ULONG refcount;
14026 HWND window;
14027 HRESULT hr;
14029 window = create_window();
14030 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14031 ok(!!d3d, "Failed to create a D3D object.\n");
14032 if (!(device = create_device(d3d, window, window, TRUE)))
14034 skip("Failed to create a D3D device, skipping tests.\n");
14035 goto done;
14038 vp.X = 0;
14039 vp.Y = 0;
14040 vp.Width = 640;
14041 vp.Height = 480;
14042 vp.MinZ = 0.0;
14043 vp.MaxZ = 1.0;
14045 hr = IDirect3DDevice9_SetViewport(device, &vp);
14046 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
14048 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
14049 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14050 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
14051 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
14052 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
14053 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
14054 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
14055 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14056 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 320, 240, D3DFMT_D24S8, 0, 0, FALSE, &ds3, NULL);
14057 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
14059 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14060 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14061 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14062 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14063 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
14064 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14065 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
14066 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14068 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14069 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14070 SetRect(&dst_rect, 0, 0, 480, 360);
14071 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
14072 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14073 SetRect(&dst_rect, 0, 0, 320, 240);
14074 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
14075 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14077 /* Partial blit. */
14078 SetRect(&src_rect, 0, 0, 320, 240);
14079 SetRect(&dst_rect, 0, 0, 320, 240);
14080 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
14081 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14082 /* Flipped. */
14083 SetRect(&src_rect, 0, 0, 640, 480);
14084 SetRect(&dst_rect, 0, 480, 640, 0);
14085 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
14086 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14087 /* Full, explicit. */
14088 SetRect(&src_rect, 0, 0, 640, 480);
14089 SetRect(&dst_rect, 0, 0, 640, 480);
14090 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
14091 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14092 /* Filtered blit. */
14093 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
14094 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14095 /* Depth -> color blit.*/
14096 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
14097 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14098 IDirect3DSurface9_Release(backbuffer);
14099 /* Full surface, different sizes */
14100 hr = IDirect3DDevice9_StretchRect(device, ds3, NULL, ds1, NULL, D3DTEXF_POINT);
14101 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14102 hr = IDirect3DDevice9_StretchRect(device, ds1, NULL, ds3, NULL, D3DTEXF_POINT);
14103 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14105 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
14106 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14107 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
14108 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14109 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
14110 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14112 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
14113 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14114 hr = IDirect3DDevice9_BeginScene(device);
14115 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14116 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
14117 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14118 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
14119 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14120 hr = IDirect3DDevice9_EndScene(device);
14121 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14123 for (i = 0; i < 4; ++i)
14125 for (j = 0; j < 4; ++j)
14127 unsigned int x = 80 * ((2 * j) + 1);
14128 unsigned int y = 60 * ((2 * i) + 1);
14129 color = getPixelColor(device, x, y);
14130 ok(color_match(color, expected_colors[i][j], 0),
14131 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
14135 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14136 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14138 IDirect3DSurface9_Release(ds3);
14139 IDirect3DSurface9_Release(ds2);
14140 IDirect3DSurface9_Release(ds1);
14141 refcount = IDirect3DDevice9_Release(device);
14142 ok(!refcount, "Device has %u references left.\n", refcount);
14143 done:
14144 IDirect3D9_Release(d3d);
14145 DestroyWindow(window);
14148 static void intz_test(void)
14150 static const DWORD ps_code[] =
14152 0xffff0200, /* ps_2_0 */
14153 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
14154 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
14155 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
14156 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
14157 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
14158 0x03010042, 0x800f0001, 0xb0e40000, 0xa0e40800, /* texldp r1, t0, s0 */
14159 0x02000001, 0x80020000, 0x80000001, /* mov r0.y, r1.x */
14160 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14161 0x0000ffff, /* end */
14163 struct
14165 float x, y, z;
14166 float s, t, p, q;
14168 quad[] =
14170 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
14171 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
14172 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
14173 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
14175 half_quad_1[] =
14177 { -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
14178 { 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
14179 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
14180 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
14182 half_quad_2[] =
14184 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
14185 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
14186 { -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
14187 { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
14189 struct
14191 UINT x, y;
14192 D3DCOLOR color;
14194 expected_colors[] =
14196 { 80, 100, 0x20204020},
14197 {240, 100, 0x6060bf60},
14198 {400, 100, 0x9f9f409f},
14199 {560, 100, 0xdfdfbfdf},
14200 { 80, 450, 0x20204020},
14201 {240, 450, 0x6060bf60},
14202 {400, 450, 0x9f9f409f},
14203 {560, 450, 0xdfdfbfdf},
14206 IDirect3DSurface9 *original_rt, *rt;
14207 struct surface_readback rb;
14208 IDirect3DTexture9 *texture;
14209 IDirect3DPixelShader9 *ps;
14210 IDirect3DDevice9 *device;
14211 IDirect3DSurface9 *ds;
14212 IDirect3D9 *d3d;
14213 ULONG refcount;
14214 D3DCAPS9 caps;
14215 HWND window;
14216 HRESULT hr;
14217 UINT i;
14219 window = create_window();
14220 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14221 ok(!!d3d, "Failed to create a D3D object.\n");
14222 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
14223 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
14225 skip("No INTZ support, skipping INTZ test.\n");
14226 goto done;
14228 if (!(device = create_device(d3d, window, window, TRUE)))
14230 skip("Failed to create a D3D device, skipping tests.\n");
14231 goto done;
14234 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14235 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
14236 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
14238 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
14239 IDirect3DDevice9_Release(device);
14240 goto done;
14242 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
14244 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
14245 IDirect3DDevice9_Release(device);
14246 goto done;
14249 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14250 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14252 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
14253 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
14254 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
14255 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
14256 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
14257 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
14258 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
14259 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
14261 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
14262 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14263 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14264 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14265 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
14266 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14267 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14268 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14269 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14270 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14272 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
14273 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14274 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
14275 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14276 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
14277 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14278 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
14279 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14280 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
14281 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14283 /* Render offscreen, using the INTZ texture as depth buffer */
14284 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14285 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14286 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14287 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14288 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14289 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14290 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14291 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14293 /* Setup the depth/stencil surface. */
14294 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14295 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14297 hr = IDirect3DDevice9_BeginScene(device);
14298 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14299 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14300 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14301 hr = IDirect3DDevice9_EndScene(device);
14302 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14304 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14305 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14306 IDirect3DSurface9_Release(ds);
14307 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14308 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14309 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14310 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14311 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14312 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14314 /* Read the depth values back. */
14315 hr = IDirect3DDevice9_BeginScene(device);
14316 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14317 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14318 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14319 hr = IDirect3DDevice9_EndScene(device);
14320 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14322 get_rt_readback(original_rt, &rb);
14323 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14325 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
14326 ok(color_match(color, expected_colors[i].color, 1),
14327 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14328 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14330 release_surface_readback(&rb);
14332 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14333 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14335 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14336 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14337 IDirect3DTexture9_Release(texture);
14339 /* Render onscreen while using the INTZ texture as depth buffer */
14340 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
14341 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
14342 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14343 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14344 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14345 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14346 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14347 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14349 /* Setup the depth/stencil surface. */
14350 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14351 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14353 hr = IDirect3DDevice9_BeginScene(device);
14354 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14355 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14356 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14357 hr = IDirect3DDevice9_EndScene(device);
14358 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14360 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14361 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14362 IDirect3DSurface9_Release(ds);
14363 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14364 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14365 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14366 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14368 /* Read the depth values back. */
14369 hr = IDirect3DDevice9_BeginScene(device);
14370 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14371 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14372 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14373 hr = IDirect3DDevice9_EndScene(device);
14374 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14376 get_rt_readback(original_rt, &rb);
14377 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14379 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
14380 ok(color_match(color, expected_colors[i].color, 1),
14381 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14382 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14384 release_surface_readback(&rb);
14386 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14387 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14389 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14390 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14391 IDirect3DTexture9_Release(texture);
14393 /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
14394 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
14395 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
14396 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14397 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14399 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14400 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14401 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14402 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14403 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14404 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14406 /* Setup the depth/stencil surface. */
14407 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14408 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14410 hr = IDirect3DDevice9_BeginScene(device);
14411 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14412 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
14413 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14414 hr = IDirect3DDevice9_EndScene(device);
14415 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14417 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14418 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14420 hr = IDirect3DDevice9_BeginScene(device);
14421 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14422 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
14423 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14424 hr = IDirect3DDevice9_EndScene(device);
14425 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14427 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14428 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14429 IDirect3DSurface9_Release(ds);
14430 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14431 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14432 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14433 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14435 /* Read the depth values back. */
14436 hr = IDirect3DDevice9_BeginScene(device);
14437 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14438 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14439 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14440 hr = IDirect3DDevice9_EndScene(device);
14441 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14443 get_rt_readback(original_rt, &rb);
14444 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14446 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
14447 ok(color_match(color, expected_colors[i].color, 1),
14448 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14449 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14451 release_surface_readback(&rb);
14453 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14454 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14456 IDirect3DTexture9_Release(texture);
14457 IDirect3DPixelShader9_Release(ps);
14458 IDirect3DSurface9_Release(original_rt);
14459 IDirect3DSurface9_Release(rt);
14460 refcount = IDirect3DDevice9_Release(device);
14461 ok(!refcount, "Device has %u references left.\n", refcount);
14462 done:
14463 IDirect3D9_Release(d3d);
14464 DestroyWindow(window);
14467 static void shadow_test(void)
14469 static const DWORD ps_code[] =
14471 0xffff0200, /* ps_2_0 */
14472 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
14473 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
14474 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
14475 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
14476 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
14477 0x03010042, 0x800f0001, 0xb0e40000, 0xa0e40800, /* texldp r1, t0, s0 */
14478 0x02000001, 0x80020000, 0x80000001, /* mov r0.y, r1.x */
14479 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14480 0x0000ffff, /* end */
14482 struct
14484 D3DFORMAT format;
14485 const char *name;
14487 formats[] =
14489 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
14490 {D3DFMT_D32, "D3DFMT_D32"},
14491 {D3DFMT_D15S1, "D3DFMT_D15S1"},
14492 {D3DFMT_D24S8, "D3DFMT_D24S8"},
14493 {D3DFMT_D24X8, "D3DFMT_D24X8"},
14494 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
14495 {D3DFMT_D16, "D3DFMT_D16"},
14496 {D3DFMT_D32F_LOCKABLE, "D3DFMT_D32F_LOCKABLE"},
14497 {D3DFMT_D24FS8, "D3DFMT_D24FS8"},
14499 struct
14501 float x, y, z;
14502 float s, t, p, q;
14504 quad[] =
14506 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
14507 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
14508 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
14509 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
14511 struct
14513 UINT x, y;
14514 D3DCOLOR color;
14516 expected_colors[] =
14518 {400, 60, 0x00000000},
14519 {560, 180, 0xffff00ff},
14520 {560, 300, 0xffff00ff},
14521 {400, 420, 0xffffffff},
14522 {240, 420, 0xffffffff},
14523 { 80, 300, 0x00000000},
14524 { 80, 180, 0x00000000},
14525 {240, 60, 0x00000000},
14528 IDirect3DSurface9 *original_ds, *original_rt, *rt;
14529 struct surface_readback rb;
14530 IDirect3DPixelShader9 *ps;
14531 IDirect3DDevice9 *device;
14532 IDirect3D9 *d3d;
14533 ULONG refcount;
14534 D3DCAPS9 caps;
14535 HWND window;
14536 HRESULT hr;
14537 UINT i;
14539 window = create_window();
14540 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14541 ok(!!d3d, "Failed to create a D3D object.\n");
14542 if (!(device = create_device(d3d, window, window, TRUE)))
14544 skip("Failed to create a D3D device, skipping tests.\n");
14545 goto done;
14548 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14549 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
14550 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
14552 skip("No pixel shader 2.0 support, skipping shadow test.\n");
14553 IDirect3DDevice9_Release(device);
14554 goto done;
14557 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14558 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14559 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
14560 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
14562 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
14563 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
14564 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
14565 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
14566 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
14568 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
14569 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14570 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14571 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14572 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
14573 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14574 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14575 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14576 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14577 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14579 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
14580 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14581 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
14582 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14583 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
14584 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14585 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
14586 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14587 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
14588 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14590 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
14592 D3DFORMAT format = formats[i].format;
14593 IDirect3DTexture9 *texture;
14594 IDirect3DSurface9 *ds;
14595 unsigned int j;
14597 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
14598 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format)))
14599 continue;
14601 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
14602 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
14603 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
14605 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14606 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14608 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14609 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14611 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14612 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14614 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14615 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14617 /* Setup the depth/stencil surface. */
14618 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14619 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14621 hr = IDirect3DDevice9_BeginScene(device);
14622 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14623 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14624 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14625 hr = IDirect3DDevice9_EndScene(device);
14626 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14628 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14629 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14630 IDirect3DSurface9_Release(ds);
14632 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14633 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14635 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14636 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14638 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14639 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14641 /* Do the actual shadow mapping. */
14642 hr = IDirect3DDevice9_BeginScene(device);
14643 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14644 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14645 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14646 hr = IDirect3DDevice9_EndScene(device);
14647 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14649 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14650 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14651 IDirect3DTexture9_Release(texture);
14653 get_rt_readback(original_rt, &rb);
14654 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
14656 D3DCOLOR color = get_readback_color(&rb, expected_colors[j].x, expected_colors[j].y);
14657 ok(color_match(color, expected_colors[j].color, 0),
14658 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
14659 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
14660 formats[i].name, color);
14662 release_surface_readback(&rb);
14664 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14665 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14668 IDirect3DPixelShader9_Release(ps);
14669 IDirect3DSurface9_Release(original_ds);
14670 IDirect3DSurface9_Release(original_rt);
14671 IDirect3DSurface9_Release(rt);
14672 refcount = IDirect3DDevice9_Release(device);
14673 ok(!refcount, "Device has %u references left.\n", refcount);
14674 done:
14675 IDirect3D9_Release(d3d);
14676 DestroyWindow(window);
14679 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
14681 static const struct
14683 struct vec3 position;
14684 DWORD diffuse;
14686 quad1[] =
14688 {{-1.0f, -1.0f, 0.0f}, 0xfff9e814},
14689 {{-1.0f, 1.0f, 0.0f}, 0xfff9e814},
14690 {{ 1.0f, -1.0f, 0.0f}, 0xfff9e814},
14691 {{ 1.0f, 1.0f, 0.0f}, 0xfff9e814},
14693 quad2[] =
14695 {{-1.0f, -1.0f, 0.0f}, 0xff002b7f},
14696 {{-1.0f, 1.0f, 0.0f}, 0xff002b7f},
14697 {{ 1.0f, -1.0f, 0.0f}, 0xff002b7f},
14698 {{ 1.0f, 1.0f, 0.0f}, 0xff002b7f},
14700 D3DCOLOR color;
14701 HRESULT hr;
14703 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
14704 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14706 hr = IDirect3DDevice9_BeginScene(device);
14707 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14709 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
14710 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14712 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
14713 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14714 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
14715 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14717 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
14718 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14719 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
14720 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14722 hr = IDirect3DDevice9_EndScene(device);
14723 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14725 color = getPixelColor(device, 1, 240);
14726 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
14727 color = getPixelColor(device, 638, 240);
14728 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
14730 color = getPixelColor(device, 1, 241);
14731 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
14732 color = getPixelColor(device, 638, 241);
14733 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
14736 static void clip_planes_test(void)
14738 IDirect3DSurface9 *offscreen_surface, *original_rt;
14739 IDirect3DTexture9 *offscreen = NULL;
14740 IDirect3DVertexShader9 *shader;
14741 IDirect3DDevice9 *device;
14742 IDirect3D9 *d3d;
14743 ULONG refcount;
14744 D3DCAPS9 caps;
14745 HWND window;
14746 HRESULT hr;
14748 static const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
14749 static const DWORD shader_code[] =
14751 0xfffe0200, /* vs_2_0 */
14752 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
14753 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
14754 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
14755 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
14756 0x0000ffff /* end */
14759 window = create_window();
14760 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14761 ok(!!d3d, "Failed to create a D3D object.\n");
14762 if (!(device = create_device(d3d, window, window, TRUE)))
14764 skip("Failed to create a D3D device, skipping tests.\n");
14765 goto done;
14768 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14769 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
14770 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
14772 skip("No vs_2_0 support, skipping tests.\n");
14773 IDirect3DDevice9_Release(device);
14774 goto done;
14777 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14778 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14780 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14781 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14782 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
14783 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14784 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
14785 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14786 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
14787 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14789 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
14790 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
14791 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14792 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
14794 IDirect3DDevice9_SetClipPlane(device, 0, plane0);
14796 clip_planes(device, "Onscreen FFP");
14798 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
14799 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
14800 hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
14801 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14802 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
14803 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
14805 clip_planes(device, "Offscreen FFP");
14807 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14808 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14810 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
14811 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
14812 hr = IDirect3DDevice9_SetVertexShader(device, shader);
14813 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
14815 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14816 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
14818 clip_planes(device, "Onscreen vertex shader");
14820 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
14821 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
14823 clip_planes(device, "Offscreen vertex shader");
14825 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14826 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14828 IDirect3DVertexShader9_Release(shader);
14829 IDirect3DSurface9_Release(original_rt);
14830 IDirect3DSurface9_Release(offscreen_surface);
14831 IDirect3DTexture9_Release(offscreen);
14832 refcount = IDirect3DDevice9_Release(device);
14833 ok(!refcount, "Device has %u references left.\n", refcount);
14834 done:
14835 IDirect3D9_Release(d3d);
14836 DestroyWindow(window);
14839 static void fp_special_test(void)
14841 /* Microsoft's assembler generates nan and inf with "1.#QNAN" and "1.#INF." respectively */
14842 static const DWORD vs_header[] =
14844 0xfffe0200, /* vs_2_0 */
14845 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
14846 0x05000051, 0xa00f0001, 0x7fc00000, 0xff800000, 0x7f800000, 0x00000000, /* def c1, nan, -inf, inf, 0 */
14847 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
14848 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
14851 static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001}; /* log r0.x, v1.x */
14852 static const DWORD vs_pow[] =
14853 {0x03000020, 0x80010000, 0x90000001, 0x90000001}; /* pow r0.x, v1.x, v1.x */
14854 static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001}; /* nrm r0.xyz, v1.x */
14855 static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001}; /* rcp r0.x, v1.x */
14856 static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001}; /* rcp r0.x, -v1.x */
14857 static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001}; /* rsq r0.x, v1.x */
14858 static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001}; /* rsq r0.x, -v1.x */
14859 static const DWORD vs_lit[] = {0x02000010, 0x800f0000, 0x90000001, /* lit r0, v1.xxxx */
14860 0x02000001, 0x80010000, 0x80aa0000}; /* mov r0.x, v0.z */
14861 static const DWORD vs_def1[] = {0x02000001, 0x80010000, 0xa0000001}; /* mov r0.x, c1.x */
14862 static const DWORD vs_def2[] = {0x02000001, 0x80010000, 0xa0550001}; /* mov r0.x, c1.y */
14863 static const DWORD vs_def3[] = {0x02000001, 0x80010000, 0xa0aa0001}; /* mov r0.x, c1.z */
14865 static const DWORD vs_footer[] =
14867 0x03000005, 0x80020000, 0x80000000, 0xa0ff0000, /* mul r0.y, r0.x, c0.w */
14868 0x0300000d, 0x80040000, 0x80000000, 0x80550000, /* sge r0.z, r0.x, r0.y */
14869 0x0300000d, 0x80020000, 0x80e40000, 0x80000000, /* sge r0.y, r0, r0.x */
14870 0x03000005, 0x80040000, 0x80550000, 0x80e40000, /* mul r0.z, r0.y, r0 */
14871 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
14872 0x0300000c, 0x80020000, 0x80000000, 0x80000000, /* slt r0.y, r0.x, r0.x */
14873 0x03000002, 0x80040000, 0x80550000, 0x80550000, /* add r0.z, r0.y, r0.y */
14874 0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000, /* slt r0.y, c0.x, r0.w */
14875 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
14876 0x03000002, 0x80040000, 0x81550000, 0xa0e40000, /* add r0.z, -r0.y, c0 */
14877 0x0300000c, 0x80080000, 0xa0000000, 0x80e40000, /* slt r0.w, c0.x, r0 */
14878 0x03000005, 0x80040000, 0x80ff0000, 0x80e40000, /* mul r0.z, r0.w, r0 */
14879 0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000, /* mad r0.y, r0.z, c0, r0 */
14880 0x02000001, 0xe0030000, 0x80e40000, /* mov oT0.xy, r0 */
14881 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
14882 0x0000ffff, /* end */
14885 static const struct
14887 const char *name;
14888 const DWORD *ops;
14889 DWORD size;
14890 D3DCOLOR r500;
14891 D3DCOLOR r600;
14892 D3DCOLOR nv40;
14893 D3DCOLOR nv50;
14894 D3DCOLOR warp;
14896 vs_body[] =
14898 /* The basic ideas here are:
14899 * 2.0 * +/-INF == +/-INF
14900 * NAN != NAN
14902 * The vertex shader value is written to the red component, with 0.0
14903 * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
14904 * result in 0x00. The pixel shader value is written to the green
14905 * component, but here 0.0 also results in 0x00. The actual value is
14906 * written to the blue component.
14908 * There are considerable differences between graphics cards in how
14909 * these are handled, but pow and nrm never generate INF or NAN on
14910 * real hardware. */
14911 {"log", vs_log, sizeof(vs_log), 0x00000000, 0x00000000, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
14912 {"pow", vs_pow, sizeof(vs_pow), 0x000000ff, 0x000000ff, 0x0000ff00, 0x000000ff, 0x00008000},
14913 {"nrm", vs_nrm, sizeof(vs_nrm), 0x00ff0000, 0x00ff0000, 0x0000ff00, 0x00ff0000, 0x00008000},
14914 {"rcp1", vs_rcp1, sizeof(vs_rcp1), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
14915 {"rcp2", vs_rcp2, sizeof(vs_rcp2), 0x000000ff, 0x00000000, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
14916 {"rsq1", vs_rsq1, sizeof(vs_rsq1), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
14917 {"rsq2", vs_rsq2, sizeof(vs_rsq2), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
14918 {"lit", vs_lit, sizeof(vs_lit), 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
14919 {"def1", vs_def1, sizeof(vs_def1), 0x000000ff, 0x00007f00, 0x0000ff00, 0x00007f00, 0x00008000},
14920 {"def2", vs_def2, sizeof(vs_def2), 0x00ff0000, 0x00ff7f00, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
14921 {"def3", vs_def3, sizeof(vs_def3), 0x00ff00ff, 0x00ff7f00, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
14924 static const DWORD ps_code[] =
14926 0xffff0200, /* ps_2_0 */
14927 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
14928 0x0200001f, 0x80000000, 0xb0030000, /* dcl t0.xy */
14929 0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000, /* max r1.x, t0, c0 */
14930 0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000, /* min r0.x, t0, c0 */
14931 0x03000002, 0x80010000, 0x80e40000, 0x81e40001, /* add r0.x, r0, -r1 */
14932 0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000, /* mad r1.x, t0, c0.w. -t0 */
14933 0x02000023, 0x80010002, 0x80e40001, /* abs r2.x, r1 */
14934 0x02000023, 0x80010000, 0x80e40000, /* abs r0.x, r0 */
14935 0x02000023, 0x80010001, 0xb0e40000, /* abs r1.x, t0 */
14936 0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r2, c0.z, c0 */
14937 0x02000023, 0x80010002, 0x80e40002, /* abs r2.x, r2 */
14938 0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r1.x, -r1, c0.z, c0 */
14939 0x02000023, 0x80010001, 0x80e40001, /* abs r1.x, r1 */
14940 0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r3.x, -r2, c0.z, c0 */
14941 0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r1, c0.z, c0 */
14942 0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000, /* cmp r0.x, -r0, c0.y, c0 */
14943 0x03000005, 0x80010002, 0x80e40002, 0x80e40003, /* mul r2.x, r2, r3 */
14944 0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000, /* cmp r0.x, -r2, c0.z, r0 */
14945 0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000, /* cmp r0.y, -r1.x, r0.x, c0.x */
14946 0x02000001, 0x80050000, 0xb0c90000, /* mov r0.xz, t0.yzxw */
14947 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.w, c0.z */
14948 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14949 0x0000ffff, /* end */
14952 struct
14954 float x, y, z;
14955 float s;
14957 quad[] =
14959 { -1.0f, 1.0f, 0.0f, 0.0f},
14960 { 1.0f, 1.0f, 1.0f, 0.0f},
14961 { -1.0f, -1.0f, 0.0f, 0.0f},
14962 { 1.0f, -1.0f, 1.0f, 0.0f},
14965 IDirect3DPixelShader9 *ps;
14966 IDirect3DDevice9 *device;
14967 UINT body_size = 0;
14968 IDirect3D9 *d3d;
14969 DWORD *vs_code;
14970 ULONG refcount;
14971 D3DCAPS9 caps;
14972 HWND window;
14973 HRESULT hr;
14974 UINT i;
14976 window = create_window();
14977 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14978 ok(!!d3d, "Failed to create a D3D object.\n");
14979 if (!(device = create_device(d3d, window, window, TRUE)))
14981 skip("Failed to create a D3D device, skipping tests.\n");
14982 goto done;
14985 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14986 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
14987 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
14989 skip("No shader model 2.0 support, skipping floating point specials test.\n");
14990 IDirect3DDevice9_Release(device);
14991 goto done;
14994 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
14995 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14997 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
14998 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
14999 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15000 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
15002 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
15003 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15005 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
15006 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
15008 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
15010 if (vs_body[i].size > body_size) body_size = vs_body[i].size;
15013 vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
15014 memcpy(vs_code, vs_header, sizeof(vs_header));
15016 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
15018 DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
15019 IDirect3DVertexShader9 *vs;
15020 D3DCOLOR color;
15022 memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
15023 offset += vs_body[i].size / sizeof(*vs_body[i].ops);
15024 memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
15026 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
15027 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
15028 hr = IDirect3DDevice9_SetVertexShader(device, vs);
15029 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
15031 hr = IDirect3DDevice9_BeginScene(device);
15032 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15033 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15034 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15035 hr = IDirect3DDevice9_EndScene(device);
15036 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15038 color = getPixelColor(device, 320, 240);
15039 ok(color_match(color, vs_body[i].r500, 1)
15040 || color_match(color, vs_body[i].r600, 1)
15041 || color_match(color, vs_body[i].nv40, 1)
15042 || color_match(color, vs_body[i].nv50, 1)
15043 || broken(color_match(color, vs_body[i].warp, 1)),
15044 "Expected color 0x%08x, 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
15045 vs_body[i].r500, vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
15047 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15048 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
15050 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
15051 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
15052 IDirect3DVertexShader9_Release(vs);
15055 HeapFree(GetProcessHeap(), 0, vs_code);
15057 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
15058 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
15059 IDirect3DPixelShader9_Release(ps);
15060 refcount = IDirect3DDevice9_Release(device);
15061 ok(!refcount, "Device has %u references left.\n", refcount);
15062 done:
15063 IDirect3D9_Release(d3d);
15064 DestroyWindow(window);
15067 static void srgbwrite_format_test(void)
15069 IDirect3D9 *d3d;
15070 IDirect3DSurface9 *rt, *backbuffer;
15071 IDirect3DTexture9 *texture;
15072 IDirect3DDevice9 *device;
15073 ULONG refcount;
15074 HWND window;
15075 HRESULT hr;
15076 int i;
15077 DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
15078 static const struct
15080 D3DFORMAT fmt;
15081 const char *name;
15083 formats[] =
15085 { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
15086 { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
15087 { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
15088 { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
15089 { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
15091 static const struct
15093 float x, y, z;
15094 float u, v;
15096 quad[] =
15098 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
15099 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
15100 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
15101 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
15104 window = create_window();
15105 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15106 ok(!!d3d, "Failed to create a D3D object.\n");
15107 if (!(device = create_device(d3d, window, window, TRUE)))
15109 skip("Failed to create a D3D device, skipping tests.\n");
15110 goto done;
15113 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
15114 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15115 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
15116 ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
15117 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
15118 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
15119 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
15120 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15122 for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
15124 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
15125 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
15127 skip("Format %s not supported as render target, skipping test.\n",
15128 formats[i].name);
15129 continue;
15132 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET,
15133 formats[i].fmt, D3DPOOL_DEFAULT, &texture, NULL);
15134 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
15135 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
15136 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
15138 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
15139 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
15140 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15141 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
15142 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
15143 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
15145 hr = IDirect3DDevice9_BeginScene(device);
15146 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15148 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
15149 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
15150 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
15151 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
15152 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15153 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15155 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
15156 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
15157 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
15158 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15159 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
15160 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
15161 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
15162 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
15163 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15164 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15165 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15166 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
15168 hr = IDirect3DDevice9_EndScene(device);
15169 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15171 IDirect3DSurface9_Release(rt);
15172 IDirect3DTexture9_Release(texture);
15174 color = getPixelColor(device, 360, 240);
15175 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
15176 D3DUSAGE_QUERY_SRGBWRITE,
15177 D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
15179 /* Big slop for R5G6B5 */
15180 ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
15181 formats[i].name, color_srgb, color);
15183 else
15185 /* Big slop for R5G6B5 */
15186 ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
15187 formats[i].name, color_rgb, color);
15190 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15191 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
15194 IDirect3DSurface9_Release(backbuffer);
15195 refcount = IDirect3DDevice9_Release(device);
15196 ok(!refcount, "Device has %u references left.\n", refcount);
15197 done:
15198 IDirect3D9_Release(d3d);
15199 DestroyWindow(window);
15202 static void ds_size_test(void)
15204 IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
15205 IDirect3DDevice9 *device;
15206 DWORD num_passes;
15207 IDirect3D9 *d3d;
15208 ULONG refcount;
15209 HWND window;
15210 HRESULT hr;
15212 static const struct
15214 float x, y, z;
15216 quad[] =
15218 {-1.0f, -1.0f, 0.0f},
15219 {-1.0f, 1.0f, 0.0f},
15220 { 1.0f, -1.0f, 0.0f},
15221 { 1.0f, 1.0f, 0.0f},
15224 window = create_window();
15225 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15226 ok(!!d3d, "Failed to create a D3D object.\n");
15227 if (!(device = create_device(d3d, window, window, TRUE)))
15229 skip("Failed to create a D3D device, skipping tests.\n");
15230 goto done;
15233 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
15234 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
15235 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
15236 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#x.\n", hr);
15237 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
15238 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
15240 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
15241 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
15243 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
15244 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15245 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
15246 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15247 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
15248 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15249 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15250 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
15251 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
15252 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
15253 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
15254 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#x.\n", hr);
15255 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15256 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
15257 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15258 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
15259 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15260 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
15262 /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
15263 * but does not change the surface's contents. */
15264 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
15265 ok(SUCCEEDED(hr), "Target clear failed, hr %#x.\n", hr);
15266 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
15267 ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#x.\n", hr);
15268 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
15269 ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#x.\n", hr);
15271 /* Nvidia does not clear the surface(The color is still 0x000000ff), AMD does(the color is 0x00ff0000) */
15273 /* Turning on any depth-related state results in a ValidateDevice failure */
15274 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15275 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15276 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15277 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
15278 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
15279 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
15280 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15281 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15282 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15283 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15284 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
15285 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
15287 /* Try to draw with the device in an invalid state. */
15288 hr = IDirect3DDevice9_BeginScene(device);
15289 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15290 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15291 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15292 hr = IDirect3DDevice9_EndScene(device);
15293 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15295 /* Don't check the resulting draw unless we find an app that needs it. On
15296 * NVIDIA ValidateDevice() returns CONFLICTINGRENDERSTATE, so the result
15297 * is undefined. On AMD D3D seems to assume the stored Z buffer value is
15298 * 0.0 for all pixels, even those that are covered by the depth buffer. */
15300 hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
15301 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
15302 hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
15303 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
15304 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15305 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
15307 IDirect3DSurface9_Release(readback);
15308 IDirect3DSurface9_Release(ds);
15309 IDirect3DSurface9_Release(rt);
15310 IDirect3DSurface9_Release(old_rt);
15311 IDirect3DSurface9_Release(old_ds);
15312 refcount = IDirect3DDevice9_Release(device);
15313 ok(!refcount, "Device has %u references left.\n", refcount);
15314 done:
15315 IDirect3D9_Release(d3d);
15316 DestroyWindow(window);
15319 static void unbound_sampler_test(void)
15321 IDirect3DPixelShader9 *ps, *ps_cube, *ps_volume;
15322 IDirect3DSurface9 *rt, *old_rt;
15323 IDirect3DDevice9 *device;
15324 IDirect3D9 *d3d;
15325 ULONG refcount;
15326 D3DCAPS9 caps;
15327 DWORD color;
15328 HWND window;
15329 HRESULT hr;
15331 static const DWORD ps_code[] =
15333 0xffff0200, /* ps_2_0 */
15334 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
15335 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
15336 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
15337 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15338 0x0000ffff, /* end */
15340 static const DWORD ps_code_cube[] =
15342 0xffff0200, /* ps_2_0 */
15343 0x0200001f, 0x98000000, 0xa00f0800, /* dcl_cube s0 */
15344 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
15345 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
15346 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15347 0x0000ffff, /* end */
15349 static const DWORD ps_code_volume[] =
15351 0xffff0200, /* ps_2_0 */
15352 0x0200001f, 0xa0000000, 0xa00f0800, /* dcl_volume s0 */
15353 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
15354 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
15355 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15356 0x0000ffff, /* end */
15359 static const struct
15361 float x, y, z;
15362 float u, v;
15364 quad[] =
15366 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
15367 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
15368 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
15369 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
15372 window = create_window();
15373 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15374 ok(!!d3d, "Failed to create a D3D object.\n");
15375 if (!(device = create_device(d3d, window, window, TRUE)))
15377 skip("Failed to create a D3D device, skipping tests.\n");
15378 goto done;
15381 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15382 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
15383 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
15385 skip("No ps_2_0 support, skipping tests.\n");
15386 IDirect3DDevice9_Release(device);
15387 goto done;
15389 if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP) || !(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
15391 skip("No cube / volume texture support, skipping tests.\n");
15392 IDirect3DDevice9_Release(device);
15393 goto done;
15396 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15397 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStage failed, %#x.\n", hr);
15399 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
15400 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
15401 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_cube, &ps_cube);
15402 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
15403 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_volume, &ps_volume);
15404 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
15406 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
15407 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
15409 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
15410 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
15412 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15413 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
15415 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 );
15416 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
15418 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x56ffffff, 1.0f, 0);
15419 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
15421 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15422 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
15424 hr = IDirect3DDevice9_BeginScene(device);
15425 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15426 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15427 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15428 hr = IDirect3DDevice9_EndScene(device);
15429 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15431 color = getPixelColorFromSurface(rt, 32, 32);
15432 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
15434 /* Now try with a cube texture */
15435 hr = IDirect3DDevice9_SetPixelShader(device, ps_cube);
15436 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
15438 hr = IDirect3DDevice9_BeginScene(device);
15439 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15440 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15441 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15442 hr = IDirect3DDevice9_EndScene(device);
15443 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15445 color = getPixelColorFromSurface(rt, 32, 32);
15446 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
15448 /* And then with a volume texture */
15449 hr = IDirect3DDevice9_SetPixelShader(device, ps_volume);
15450 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
15452 hr = IDirect3DDevice9_BeginScene(device);
15453 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15454 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15455 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15456 hr = IDirect3DDevice9_EndScene(device);
15457 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15459 color = getPixelColorFromSurface(rt, 32, 32);
15460 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
15462 IDirect3DSurface9_Release(rt);
15463 IDirect3DSurface9_Release(old_rt);
15464 IDirect3DPixelShader9_Release(ps);
15465 IDirect3DPixelShader9_Release(ps_cube);
15466 IDirect3DPixelShader9_Release(ps_volume);
15467 refcount = IDirect3DDevice9_Release(device);
15468 ok(!refcount, "Device has %u references left.\n", refcount);
15469 done:
15470 IDirect3D9_Release(d3d);
15471 DestroyWindow(window);
15474 static void update_surface_test(void)
15476 static const BYTE blocks[][8] =
15478 {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, /* White */
15479 {0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Red */
15480 {0xe0, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00}, /* Yellow */
15481 {0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Green */
15482 {0xff, 0x07, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Cyan */
15483 {0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Blue */
15484 {0x1f, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Magenta */
15486 static const struct
15488 UINT x, y;
15489 D3DCOLOR color;
15491 expected_colors[] =
15493 { 18, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0xff)},
15494 { 57, 240, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff)},
15495 {109, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0xff)},
15496 {184, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
15497 {290, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
15498 {440, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
15499 {584, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
15501 static const struct
15503 float x, y, z, w;
15504 float u, v;
15506 tri[] =
15508 { 0.0f, 480.0f, 0.0f, 1.0f, 0.0f, 0.0f},
15509 { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
15510 {640.0f, 240.0f, 0.0f, 10.0f, 100.0f, 0.5f},
15512 static const RECT rect_2x2 = {0, 0, 2, 2};
15513 static const struct
15515 UINT src_level;
15516 UINT dst_level;
15517 const RECT *r;
15518 HRESULT hr;
15520 block_size_tests[] =
15522 {1, 0, NULL, D3D_OK},
15523 {0, 1, NULL, D3DERR_INVALIDCALL},
15524 {5, 4, NULL, D3DERR_INVALIDCALL},
15525 {4, 5, NULL, D3DERR_INVALIDCALL},
15526 {4, 5, &rect_2x2, D3DERR_INVALIDCALL},
15527 {5, 5, &rect_2x2, D3D_OK},
15530 IDirect3DSurface9 *src_surface, *dst_surface;
15531 IDirect3DTexture9 *src_tex, *dst_tex;
15532 IDirect3DDevice9 *device;
15533 IDirect3D9 *d3d;
15534 ULONG refcount;
15535 UINT count, i;
15536 HWND window;
15537 HRESULT hr;
15539 window = create_window();
15540 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15541 ok(!!d3d, "Failed to create a D3D object.\n");
15542 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15543 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1)))
15545 skip("DXT1 not supported, skipping tests.\n");
15546 goto done;
15548 if (!(device = create_device(d3d, window, window, TRUE)))
15550 skip("Failed to create a D3D device, skipping tests.\n");
15551 goto done;
15554 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &src_tex, NULL);
15555 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
15556 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &dst_tex, NULL);
15557 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
15559 count = IDirect3DTexture9_GetLevelCount(src_tex);
15560 ok(count == 7, "Got level count %u, expected 7.\n", count);
15562 for (i = 0; i < count; ++i)
15564 UINT row_count, block_count, x, y;
15565 D3DSURFACE_DESC desc;
15566 BYTE *row, *block;
15567 D3DLOCKED_RECT r;
15569 hr = IDirect3DTexture9_GetLevelDesc(src_tex, i, &desc);
15570 ok(SUCCEEDED(hr), "Failed to get level desc, hr %#x.\n", hr);
15572 hr = IDirect3DTexture9_LockRect(src_tex, i, &r, NULL, 0);
15573 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
15575 row_count = ((desc.Height + 3) & ~3) / 4;
15576 block_count = ((desc.Width + 3) & ~3) / 4;
15577 row = r.pBits;
15579 for (y = 0; y < row_count; ++y)
15581 block = row;
15582 for (x = 0; x < block_count; ++x)
15584 memcpy(block, blocks[i], sizeof(blocks[i]));
15585 block += sizeof(blocks[i]);
15587 row += r.Pitch;
15590 hr = IDirect3DTexture9_UnlockRect(src_tex, i);
15591 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
15594 for (i = 0; i < sizeof(block_size_tests) / sizeof(*block_size_tests); ++i)
15596 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, block_size_tests[i].src_level, &src_surface);
15597 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15598 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, block_size_tests[i].dst_level, &dst_surface);
15599 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15601 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, block_size_tests[i].r, dst_surface, NULL);
15602 ok(hr == block_size_tests[i].hr, "Update surface returned %#x for test %u, expected %#x.\n",
15603 hr, i, block_size_tests[i].hr);
15605 IDirect3DSurface9_Release(dst_surface);
15606 IDirect3DSurface9_Release(src_surface);
15609 for (i = 0; i < count; ++i)
15611 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, i, &src_surface);
15612 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15613 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, i, &dst_surface);
15614 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15616 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, NULL, dst_surface, NULL);
15617 ok(SUCCEEDED(hr), "Failed to update surface at level %u, hr %#x.\n", i, hr);
15619 IDirect3DSurface9_Release(dst_surface);
15620 IDirect3DSurface9_Release(src_surface);
15623 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15624 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15625 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
15626 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15627 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
15628 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15629 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)dst_tex);
15630 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
15631 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
15632 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
15633 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
15634 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
15636 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
15637 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
15639 hr = IDirect3DDevice9_BeginScene(device);
15640 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15641 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 1, tri, sizeof(*tri));
15642 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15643 hr = IDirect3DDevice9_EndScene(device);
15644 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15646 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15648 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
15649 ok(color_match(color, expected_colors[i].color, 0),
15650 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15651 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15654 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15655 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
15657 IDirect3DTexture9_Release(dst_tex);
15658 IDirect3DTexture9_Release(src_tex);
15659 refcount = IDirect3DDevice9_Release(device);
15660 ok(!refcount, "Device has %u references left.\n", refcount);
15661 done:
15662 IDirect3D9_Release(d3d);
15663 DestroyWindow(window);
15666 static void multisample_get_rtdata_test(void)
15668 IDirect3DSurface9 *original_ds, *original_rt, *rt, *readback;
15669 IDirect3DDevice9 *device;
15670 IDirect3D9 *d3d;
15671 ULONG refcount;
15672 HWND window;
15673 HRESULT hr;
15675 window = create_window();
15676 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15677 ok(!!d3d, "Failed to create a D3D object.\n");
15678 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15679 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15681 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping tests.\n");
15682 goto done;
15684 if (!(device = create_device(d3d, window, window, TRUE)))
15686 skip("Failed to create a D3D device, skipping tests.\n");
15687 goto done;
15690 hr = IDirect3DDevice9_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
15691 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
15692 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
15693 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_A8R8G8B8,
15694 D3DPOOL_SYSTEMMEM, &readback, NULL);
15695 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
15697 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
15698 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
15699 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
15700 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
15702 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15703 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15704 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15705 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15707 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
15708 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15709 hr = IDirect3DDevice9_GetRenderTargetData(device, rt, readback);
15710 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
15712 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
15713 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15714 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15715 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
15717 IDirect3DSurface9_Release(original_ds);
15718 IDirect3DSurface9_Release(original_rt);
15719 IDirect3DSurface9_Release(readback);
15720 IDirect3DSurface9_Release(rt);
15721 refcount = IDirect3DDevice9_Release(device);
15722 ok(!refcount, "Device has %u references left.\n", refcount);
15723 done:
15724 IDirect3D9_Release(d3d);
15725 DestroyWindow(window);
15728 static void multisampled_depth_buffer_test(void)
15730 IDirect3DDevice9 *device = 0;
15731 IDirect3DSurface9 *original_rt, *rt, *readback, *ds, *original_ds;
15732 IDirect3D9 *d3d;
15733 D3DCAPS9 caps;
15734 HRESULT hr;
15735 D3DPRESENT_PARAMETERS present_parameters;
15736 unsigned int i;
15737 static const struct
15739 float x, y, z;
15740 D3DCOLOR color;
15742 quad_1[] =
15744 { -1.0f, 1.0f, 0.0f, 0xffff0000},
15745 { 1.0f, 1.0f, 1.0f, 0xffff0000},
15746 { -1.0f, -1.0f, 0.0f, 0xffff0000},
15747 { 1.0f, -1.0f, 1.0f, 0xffff0000},
15749 quad_2[] =
15751 { -1.0f, 1.0f, 1.0f, 0xff0000ff},
15752 { 1.0f, 1.0f, 0.0f, 0xff0000ff},
15753 { -1.0f, -1.0f, 1.0f, 0xff0000ff},
15754 { 1.0f, -1.0f, 0.0f, 0xff0000ff},
15756 static const struct
15758 UINT x, y;
15759 D3DCOLOR color;
15761 expected_colors[] =
15763 { 80, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15764 {240, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15765 {400, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15766 {560, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15767 { 80, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15768 {240, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15769 {400, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15770 {560, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15773 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15774 ok(!!d3d, "Failed to create a D3D object.\n");
15776 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
15777 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15779 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled depth buffer test.\n");
15780 IDirect3D9_Release(d3d);
15781 return;
15783 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
15784 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15786 skip("Multisampling not supported for D3DFMT_D24S8, skipping multisampled depth buffer test.\n");
15787 IDirect3D9_Release(d3d);
15788 return;
15791 ZeroMemory(&present_parameters, sizeof(present_parameters));
15792 present_parameters.Windowed = TRUE;
15793 present_parameters.hDeviceWindow = create_window();
15794 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
15795 present_parameters.BackBufferWidth = 640;
15796 present_parameters.BackBufferHeight = 480;
15797 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
15798 present_parameters.EnableAutoDepthStencil = TRUE;
15799 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
15800 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
15802 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15803 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
15804 &present_parameters, &device);
15805 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
15807 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15808 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
15809 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
15811 skip("No unconditional NP2 texture support, skipping multisampled depth buffer test.\n");
15812 goto cleanup;
15815 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15816 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
15817 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
15818 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15819 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
15820 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
15822 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
15823 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
15824 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
15825 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
15827 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15828 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15829 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15830 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15831 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15832 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15833 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
15834 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15835 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
15836 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15838 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
15839 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15841 /* Render onscreen and then offscreen */
15842 hr = IDirect3DDevice9_BeginScene(device);
15843 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15844 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
15845 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15846 hr = IDirect3DDevice9_EndScene(device);
15847 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15849 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, rt, NULL, D3DTEXF_POINT);
15850 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15851 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15852 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15854 hr = IDirect3DDevice9_BeginScene(device);
15855 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15856 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
15857 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15858 hr = IDirect3DDevice9_EndScene(device);
15859 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15861 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, readback, NULL, D3DTEXF_POINT);
15862 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15864 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15866 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
15867 ok(color_match(color, expected_colors[i].color, 1),
15868 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15869 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15872 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
15873 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15874 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15875 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
15877 /* Render offscreen and then onscreen */
15878 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15879 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15880 IDirect3DSurface9_Release(ds);
15881 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
15882 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
15883 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#x.\n", hr);
15884 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15885 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15887 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
15888 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15890 hr = IDirect3DDevice9_BeginScene(device);
15891 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15892 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
15893 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15894 hr = IDirect3DDevice9_EndScene(device);
15895 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15897 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
15898 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15899 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15900 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15902 hr = IDirect3DDevice9_BeginScene(device);
15903 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15904 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
15905 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15906 hr = IDirect3DDevice9_EndScene(device);
15907 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15909 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
15910 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15912 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15914 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
15915 ok(color_match(color, expected_colors[i].color, 1),
15916 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15917 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15920 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15921 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
15923 IDirect3DSurface9_Release(ds);
15924 IDirect3DSurface9_Release(readback);
15925 IDirect3DSurface9_Release(rt);
15926 IDirect3DSurface9_Release(original_rt);
15927 cleanup_device(device);
15929 ZeroMemory(&present_parameters, sizeof(present_parameters));
15930 present_parameters.Windowed = TRUE;
15931 present_parameters.hDeviceWindow = create_window();
15932 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
15933 present_parameters.BackBufferWidth = 640;
15934 present_parameters.BackBufferHeight = 480;
15935 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
15936 present_parameters.EnableAutoDepthStencil = TRUE;
15937 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
15938 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
15940 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15941 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
15942 &present_parameters, &device);
15943 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
15945 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
15946 ok(SUCCEEDED(hr), "Failed to clear depth buffer, hr %#x.\n", hr);
15948 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15949 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
15950 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
15951 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15952 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
15953 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
15954 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
15955 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
15956 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
15958 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
15959 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
15960 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
15961 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
15962 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15963 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15964 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15965 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15967 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15968 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15969 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15970 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15971 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15972 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15973 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
15974 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15975 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
15976 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15978 /* Render to a multisampled offscreen frame buffer and then blit to
15979 * the onscreen (not multisampled) frame buffer. */
15980 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
15981 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15983 hr = IDirect3DDevice9_BeginScene(device);
15984 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15985 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
15986 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15987 hr = IDirect3DDevice9_EndScene(device);
15988 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15990 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
15991 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15992 hr = IDirect3DDevice9_StretchRect(device, ds, NULL, original_ds, NULL, D3DTEXF_POINT);
15993 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15995 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15996 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15997 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
15998 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16000 hr = IDirect3DDevice9_BeginScene(device);
16001 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16002 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
16003 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16004 hr = IDirect3DDevice9_EndScene(device);
16005 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16007 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
16008 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
16010 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16012 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
16013 ok(color_match(color, expected_colors[i].color, 1),
16014 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16015 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16018 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16019 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16021 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16022 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16023 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16024 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
16026 IDirect3DSurface9_Release(original_ds);
16027 IDirect3DSurface9_Release(original_rt);
16028 IDirect3DSurface9_Release(ds);
16029 IDirect3DSurface9_Release(readback);
16030 IDirect3DSurface9_Release(rt);
16031 cleanup:
16032 cleanup_device(device);
16033 IDirect3D9_Release(d3d);
16036 static void resz_test(void)
16038 IDirect3DDevice9 *device = 0;
16039 IDirect3DSurface9 *rt, *original_rt, *ds, *readback, *intz_ds;
16040 D3DCAPS9 caps;
16041 HRESULT hr;
16042 D3DPRESENT_PARAMETERS present_parameters;
16043 unsigned int i;
16044 static const DWORD ps_code[] =
16046 0xffff0200, /* ps_2_0 */
16047 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
16048 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
16049 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
16050 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
16051 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
16052 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
16053 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
16054 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
16055 0x02000001, 0x800f0800, 0x80e40001, /* mov oC0, r1 */
16056 0x0000ffff, /* end */
16058 struct
16060 float x, y, z;
16061 float s, t, p, q;
16063 quad[] =
16065 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
16066 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
16067 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
16068 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
16070 struct
16072 UINT x, y;
16073 D3DCOLOR color;
16075 expected_colors[] =
16077 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
16078 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
16079 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
16080 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
16081 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
16082 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
16083 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
16084 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
16086 IDirect3DTexture9 *texture;
16087 IDirect3DPixelShader9 *ps;
16088 IDirect3D9 *d3d;
16089 DWORD value;
16091 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16092 ok(!!d3d, "Failed to create a D3D object.\n");
16094 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
16095 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
16097 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
16098 IDirect3D9_Release(d3d);
16099 return;
16101 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
16102 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
16104 skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
16105 IDirect3D9_Release(d3d);
16106 return;
16109 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
16110 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
16112 skip("No INTZ support, skipping RESZ test.\n");
16113 IDirect3D9_Release(d3d);
16114 return;
16117 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
16118 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'))))
16120 skip("No RESZ support, skipping RESZ test.\n");
16121 IDirect3D9_Release(d3d);
16122 return;
16125 ZeroMemory(&present_parameters, sizeof(present_parameters));
16126 present_parameters.Windowed = TRUE;
16127 present_parameters.hDeviceWindow = create_window();
16128 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
16129 present_parameters.BackBufferWidth = 640;
16130 present_parameters.BackBufferHeight = 480;
16131 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
16132 present_parameters.EnableAutoDepthStencil = FALSE;
16133 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
16134 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
16136 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16137 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
16138 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
16140 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16141 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
16142 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
16144 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
16145 cleanup_device(device);
16146 IDirect3D9_Release(d3d);
16147 return;
16149 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
16151 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
16152 cleanup_device(device);
16153 IDirect3D9_Release(d3d);
16154 return;
16157 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
16158 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
16160 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
16161 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
16162 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
16163 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
16164 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
16165 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#x.\n", hr);
16166 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
16167 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
16168 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
16170 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
16171 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
16172 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
16173 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
16174 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
16175 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
16176 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16177 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
16178 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
16179 IDirect3DSurface9_Release(intz_ds);
16180 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
16181 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
16183 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
16184 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
16185 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
16186 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16187 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
16188 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16189 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16190 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16191 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16192 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16194 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
16195 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16196 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
16197 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16198 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
16199 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16200 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
16201 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16202 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
16203 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16205 /* Render offscreen (multisampled), blit the depth buffer
16206 * into the INTZ texture and then check its contents */
16207 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
16208 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16209 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16210 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16211 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
16212 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16214 hr = IDirect3DDevice9_BeginScene(device);
16215 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16216 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16217 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16219 /* The destination depth texture has to be bound to sampler 0 */
16220 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16221 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16223 /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
16224 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
16225 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16226 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
16227 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16228 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
16229 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16230 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16231 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16232 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
16233 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16234 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16235 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16236 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
16237 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16239 /* The actual multisampled depth buffer resolve happens here */
16240 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16241 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16242 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
16243 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
16245 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16246 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16247 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16248 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16249 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16250 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16252 /* Read the depth values back */
16253 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16254 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16255 hr = IDirect3DDevice9_EndScene(device);
16256 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16258 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16260 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
16261 ok(color_match(color, expected_colors[i].color, 1),
16262 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16263 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16266 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16267 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16269 IDirect3DSurface9_Release(ds);
16270 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16271 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16272 IDirect3DTexture9_Release(texture);
16273 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16274 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16275 IDirect3DPixelShader9_Release(ps);
16276 IDirect3DSurface9_Release(readback);
16277 IDirect3DSurface9_Release(original_rt);
16278 IDirect3DSurface9_Release(rt);
16279 cleanup_device(device);
16281 ZeroMemory(&present_parameters, sizeof(present_parameters));
16282 present_parameters.Windowed = TRUE;
16283 present_parameters.hDeviceWindow = create_window();
16284 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
16285 present_parameters.BackBufferWidth = 640;
16286 present_parameters.BackBufferHeight = 480;
16287 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
16288 present_parameters.EnableAutoDepthStencil = TRUE;
16289 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
16290 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
16292 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16293 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
16294 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
16296 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
16297 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
16298 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
16299 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
16300 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
16301 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
16302 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
16303 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
16304 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
16305 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
16306 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
16307 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
16308 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
16309 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16310 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
16311 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16312 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
16313 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
16314 IDirect3DSurface9_Release(intz_ds);
16315 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
16316 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
16318 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
16319 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
16320 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
16321 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16322 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
16323 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16324 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16325 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16326 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16327 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16329 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
16330 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16331 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
16332 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16333 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
16334 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16335 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
16336 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16337 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
16338 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16340 /* Render onscreen, blit the depth buffer into the INTZ texture
16341 * and then check its contents */
16342 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16343 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16344 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16345 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16346 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
16347 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16349 hr = IDirect3DDevice9_BeginScene(device);
16350 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16351 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16352 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16353 hr = IDirect3DDevice9_EndScene(device);
16354 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16356 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16357 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16359 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
16360 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16361 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
16362 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16363 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
16364 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16365 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16366 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16367 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
16368 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16369 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16370 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16371 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
16372 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16374 /* The actual multisampled depth buffer resolve happens here */
16375 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16376 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16377 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
16378 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
16380 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
16381 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16382 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16383 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16384 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16385 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16387 /* Read the depth values back */
16388 hr = IDirect3DDevice9_BeginScene(device);
16389 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16390 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16391 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16392 hr = IDirect3DDevice9_EndScene(device);
16393 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16395 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16397 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
16398 ok(color_match(color, expected_colors[i].color, 1),
16399 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16400 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16403 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16404 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16407 /* Test edge cases - try with no texture at all */
16408 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16409 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16410 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16411 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16412 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16413 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16414 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16415 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16417 hr = IDirect3DDevice9_BeginScene(device);
16418 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16419 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16420 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16421 hr = IDirect3DDevice9_EndScene(device);
16422 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16424 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16425 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16427 /* With a non-multisampled depth buffer */
16428 IDirect3DSurface9_Release(ds);
16429 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
16430 D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
16431 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
16433 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
16434 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16435 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16436 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16437 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16438 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16440 hr = IDirect3DDevice9_BeginScene(device);
16441 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16442 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16443 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16445 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16446 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16448 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
16449 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16450 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
16451 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16452 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
16453 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16454 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16455 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16456 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
16457 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16458 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16459 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16460 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
16461 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16462 hr = IDirect3DDevice9_EndScene(device);
16463 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16465 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16466 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16468 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16469 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16471 /* Read the depth values back. */
16472 hr = IDirect3DDevice9_BeginScene(device);
16473 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16474 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16475 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16476 hr = IDirect3DDevice9_EndScene(device);
16477 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16479 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16481 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
16482 ok(color_match(color, expected_colors[i].color, 1),
16483 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16484 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16487 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16488 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16490 /* Without a current depth-stencil buffer set */
16491 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16492 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16493 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16494 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16496 hr = IDirect3DDevice9_BeginScene(device);
16497 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16498 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16499 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16500 hr = IDirect3DDevice9_EndScene(device);
16501 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16503 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16504 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16506 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16507 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16508 IDirect3DSurface9_Release(ds);
16509 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16510 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16511 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16512 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16513 IDirect3DTexture9_Release(texture);
16514 IDirect3DPixelShader9_Release(ps);
16515 IDirect3DSurface9_Release(readback);
16516 IDirect3DSurface9_Release(original_rt);
16517 cleanup_device(device);
16518 IDirect3D9_Release(d3d);
16521 static void zenable_test(void)
16523 static const struct
16525 struct vec4 position;
16526 D3DCOLOR diffuse;
16528 tquad[] =
16530 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
16531 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xff00ff00},
16532 {{640.0f, 480.0f, 1.5f, 1.0f}, 0xff00ff00},
16533 {{640.0f, 0.0f, 1.5f, 1.0f}, 0xff00ff00},
16535 IDirect3DDevice9 *device;
16536 IDirect3D9 *d3d;
16537 D3DCOLOR color;
16538 ULONG refcount;
16539 D3DCAPS9 caps;
16540 HWND window;
16541 HRESULT hr;
16542 UINT x, y;
16543 UINT i, j;
16544 UINT test;
16545 IDirect3DSurface9 *ds;
16547 window = create_window();
16548 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16549 ok(!!d3d, "Failed to create a D3D object.\n");
16550 if (!(device = create_device(d3d, window, window, TRUE)))
16552 skip("Failed to create a D3D device, skipping tests.\n");
16553 goto done;
16556 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
16557 ok(SUCCEEDED(hr), "Failed to get depth stencil surface, hr %#x.\n", hr);
16559 for (test = 0; test < 2; ++test)
16561 /* The Windows 8 testbot (WARP) appears to clip with
16562 * ZENABLE = D3DZB_TRUE and no depth buffer set. */
16563 static const D3DCOLOR expected_broken[] =
16565 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16566 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16567 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16568 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16571 if (!test)
16573 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16574 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
16576 else
16578 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
16579 ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
16580 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16581 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
16582 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.0f, 0);
16583 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16585 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
16586 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16588 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
16589 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16590 hr = IDirect3DDevice9_BeginScene(device);
16591 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16592 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
16593 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16594 hr = IDirect3DDevice9_EndScene(device);
16595 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16597 for (i = 0; i < 4; ++i)
16599 for (j = 0; j < 4; ++j)
16601 x = 80 * ((2 * j) + 1);
16602 y = 60 * ((2 * i) + 1);
16603 color = getPixelColor(device, x, y);
16604 ok(color_match(color, 0x0000ff00, 1)
16605 || broken(color_match(color, expected_broken[i * 4 + j], 1) && !test),
16606 "Expected color 0x0000ff00 at %u, %u, got 0x%08x, test %u.\n",
16607 x, y, color, test);
16611 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16612 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
16615 IDirect3DSurface9_Release(ds);
16617 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16618 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
16620 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
16621 && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
16623 static const DWORD vs_code[] =
16625 0xfffe0101, /* vs_1_1 */
16626 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
16627 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
16628 0x00000001, 0xd00f0000, 0x90e40000, /* mov oD0, v0 */
16629 0x0000ffff
16631 static const DWORD ps_code[] =
16633 0xffff0101, /* ps_1_1 */
16634 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
16635 0x0000ffff /* end */
16637 static const struct vec3 quad[] =
16639 {-1.0f, -1.0f, -0.5f},
16640 {-1.0f, 1.0f, -0.5f},
16641 { 1.0f, -1.0f, 1.5f},
16642 { 1.0f, 1.0f, 1.5f},
16644 static const D3DCOLOR expected[] =
16646 0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
16647 0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
16648 0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
16649 0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
16651 /* The Windows 8 testbot (WARP) appears to not clip z for regular
16652 * vertices either. */
16653 static const D3DCOLOR expected_broken[] =
16655 0x0020df20, 0x0060df60, 0x009fdf9f, 0x00dfdfdf,
16656 0x00209f20, 0x00609f60, 0x009f9f9f, 0x00df9fdf,
16657 0x00206020, 0x00606060, 0x009f609f, 0x00df60df,
16658 0x00202020, 0x00602060, 0x009f209f, 0x00df20df,
16661 IDirect3DVertexShader9 *vs;
16662 IDirect3DPixelShader9 *ps;
16664 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
16665 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16666 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
16667 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
16668 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
16669 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
16670 hr = IDirect3DDevice9_SetVertexShader(device, vs);
16671 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
16672 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16673 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
16675 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
16676 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16677 hr = IDirect3DDevice9_BeginScene(device);
16678 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16679 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16680 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16681 hr = IDirect3DDevice9_EndScene(device);
16682 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16684 for (i = 0; i < 4; ++i)
16686 for (j = 0; j < 4; ++j)
16688 x = 80 * ((2 * j) + 1);
16689 y = 60 * ((2 * i) + 1);
16690 color = getPixelColor(device, x, y);
16691 ok(color_match(color, expected[i * 4 + j], 1)
16692 || broken(color_match(color, expected_broken[i * 4 + j], 1)),
16693 "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
16697 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16698 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
16700 IDirect3DPixelShader9_Release(ps);
16701 IDirect3DVertexShader9_Release(vs);
16704 refcount = IDirect3DDevice9_Release(device);
16705 ok(!refcount, "Device has %u references left.\n", refcount);
16706 done:
16707 IDirect3D9_Release(d3d);
16708 DestroyWindow(window);
16711 static void fog_special_test(void)
16713 static const struct
16715 struct vec3 position;
16716 D3DCOLOR diffuse;
16718 quad[] =
16720 {{ -1.0f, -1.0f, 0.0f}, 0xff00ff00},
16721 {{ -1.0f, 1.0f, 0.0f}, 0xff00ff00},
16722 {{ 1.0f, -1.0f, 1.0f}, 0xff00ff00},
16723 {{ 1.0f, 1.0f, 1.0f}, 0xff00ff00}
16725 static const struct
16727 DWORD vertexmode, tablemode;
16728 BOOL vs, ps;
16729 D3DCOLOR color_left, color_right;
16731 tests[] =
16733 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, FALSE, 0x00ff0000, 0x00ff0000},
16734 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, TRUE, 0x00ff0000, 0x00ff0000},
16735 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, FALSE, 0x00ff0000, 0x00ff0000},
16736 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, TRUE, 0x00ff0000, 0x00ff0000},
16738 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, FALSE, 0x0000ff00, 0x00ff0000},
16739 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, TRUE, 0x0000ff00, 0x00ff0000},
16740 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, FALSE, 0x0000ff00, 0x00ff0000},
16741 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, TRUE, 0x0000ff00, 0x00ff0000},
16743 static const DWORD pixel_shader_code[] =
16745 0xffff0101, /* ps_1_1 */
16746 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
16747 0x0000ffff
16749 static const DWORD vertex_shader_code[] =
16751 0xfffe0101, /* vs_1_1 */
16752 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
16753 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
16754 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
16755 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
16756 0x0000ffff
16758 static const D3DMATRIX identity =
16760 1.0f, 0.0f, 0.0f, 0.0f,
16761 0.0f, 1.0f, 0.0f, 0.0f,
16762 0.0f, 0.0f, 1.0f, 0.0f,
16763 0.0f, 0.0f, 0.0f, 1.0f,
16764 }}};
16765 union
16767 float f;
16768 DWORD d;
16769 } conv;
16770 DWORD color;
16771 HRESULT hr;
16772 unsigned int i;
16773 IDirect3DPixelShader9 *ps;
16774 IDirect3DVertexShader9 *vs;
16775 IDirect3DDevice9 *device;
16776 IDirect3D9 *d3d;
16777 ULONG refcount;
16778 D3DCAPS9 caps;
16779 HWND window;
16781 window = create_window();
16782 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16783 ok(!!d3d, "Failed to create a D3D object.\n");
16784 if (!(device = create_device(d3d, window, window, TRUE)))
16786 skip("Failed to create a D3D device, skipping tests.\n");
16787 goto done;
16790 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16791 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
16792 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
16794 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code, &vs);
16795 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
16797 else
16799 skip("Vertex Shaders not supported, skipping some fog tests.\n");
16800 vs = NULL;
16802 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
16804 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &ps);
16805 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
16807 else
16809 skip("Pixel Shaders not supported, skipping some fog tests.\n");
16810 ps = NULL;
16813 /* The table fog tests seem to depend on the projection matrix explicitly
16814 * being set to an identity matrix, even though that's the default.
16815 * (AMD Radeon HD 6310, Windows 7) */
16816 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
16817 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
16819 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
16820 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16821 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16822 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
16823 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
16824 ok(SUCCEEDED(hr), "Failed to enable fog, hr %#x.\n", hr);
16825 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffff0000);
16826 ok(SUCCEEDED(hr), "Failed to set fog color, hr %#x.\n", hr);
16828 conv.f = 0.5f;
16829 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, conv.d);
16830 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#x.\n", hr);
16831 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, conv.d);
16832 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#x.\n", hr);
16834 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
16836 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
16837 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16839 if (!tests[i].vs)
16841 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
16842 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
16844 else if (vs)
16846 hr = IDirect3DDevice9_SetVertexShader(device, vs);
16847 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
16849 else
16851 continue;
16854 if (!tests[i].ps)
16856 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16857 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
16859 else if (ps)
16861 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16862 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
16864 else
16866 continue;
16869 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vertexmode);
16870 ok(SUCCEEDED(hr), "Failed to set fogvertexmode, hr %#x.\n", hr);
16871 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tablemode);
16872 ok(SUCCEEDED(hr), "Failed to set fogtablemode, hr %#x.\n", hr);
16874 hr = IDirect3DDevice9_BeginScene(device);
16875 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16876 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16877 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16878 hr = IDirect3DDevice9_EndScene(device);
16879 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16881 color = getPixelColor(device, 310, 240);
16882 ok(color_match(color, tests[i].color_left, 1),
16883 "Expected left color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_left, color, i);
16884 color = getPixelColor(device, 330, 240);
16885 ok(color_match(color, tests[i].color_right, 1),
16886 "Expected right color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_right, color, i);
16888 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16889 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
16892 if (vs)
16893 IDirect3DVertexShader9_Release(vs);
16894 if (ps)
16895 IDirect3DPixelShader9_Release(ps);
16896 refcount = IDirect3DDevice9_Release(device);
16897 ok(!refcount, "Device has %u references left.\n", refcount);
16898 done:
16899 IDirect3D9_Release(d3d);
16900 DestroyWindow(window);
16903 static void volume_srgb_test(void)
16905 HRESULT hr;
16906 unsigned int i, j;
16907 IDirect3DVolumeTexture9 *tex1, *tex2;
16908 D3DPOOL pool;
16909 D3DLOCKED_BOX locked_box;
16910 IDirect3DDevice9 *device;
16911 IDirect3D9 *d3d;
16912 D3DCOLOR color;
16913 ULONG refcount;
16914 HWND window;
16916 static const struct
16918 BOOL srgb;
16919 DWORD color;
16921 tests[] =
16923 /* Try toggling on and off */
16924 { FALSE, 0x007f7f7f },
16925 { TRUE, 0x00363636 },
16926 { FALSE, 0x007f7f7f },
16928 static const struct
16930 struct vec3 pos;
16931 struct vec3 texcrd;
16933 quad[] =
16935 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
16936 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
16937 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
16938 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
16941 window = create_window();
16942 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16943 ok(!!d3d, "Failed to create a D3D object.\n");
16944 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
16945 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_VOLUMETEXTURE, D3DFMT_A8R8G8B8) != D3D_OK)
16947 skip("D3DFMT_A8R8G8B8 volume textures with SRGBREAD not supported.\n");
16948 goto done;
16950 if (!(device = create_device(d3d, window, window, TRUE)))
16952 skip("Failed to create a D3D device, skipping tests.\n");
16953 goto done;
16956 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
16957 ok(SUCCEEDED(hr), "Failed to set color op 0, hr %#x.\n", hr);
16958 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
16959 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
16960 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
16961 ok(SUCCEEDED(hr), "Failed to set color op 0, hr %#x.\n", hr);
16962 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
16963 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
16965 for (i = 0; i < 2; i++)
16967 if (!i)
16968 pool = D3DPOOL_SYSTEMMEM;
16969 else
16970 pool = D3DPOOL_MANAGED;
16972 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, 0, D3DFMT_A8R8G8B8, pool, &tex1, NULL);
16973 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
16974 hr = IDirect3DVolumeTexture9_LockBox(tex1, 0, &locked_box, NULL, 0);
16975 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
16976 *((DWORD *)locked_box.pBits) = 0x7f7f7f7f;
16977 hr = IDirect3DVolumeTexture9_UnlockBox(tex1, 0);
16978 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
16980 if (!i)
16982 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, 0,
16983 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
16984 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
16985 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex1, (IDirect3DBaseTexture9 *)tex2);
16986 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16987 IDirect3DVolumeTexture9_Release(tex1);
16989 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex2);
16990 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16991 IDirect3DVolumeTexture9_Release(tex2);
16993 else
16995 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex1);
16996 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16997 IDirect3DVolumeTexture9_Release(tex1);
17000 for (j = 0; j < sizeof(tests) / sizeof(*tests); j++)
17002 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, tests[j].srgb);
17003 ok(SUCCEEDED(hr), "Failed to set srgb state, hr %#x.\n", hr);
17005 hr = IDirect3DDevice9_BeginScene(device);
17006 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17007 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17008 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17009 hr = IDirect3DDevice9_EndScene(device);
17010 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17012 color = getPixelColor(device, 320, 240);
17013 ok(color_match(color, tests[j].color, 2),
17014 "Expected color 0x%08x, got 0x%08x, i = %u, j = %u.\n", tests[j].color, color, i, j);
17016 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17017 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
17021 refcount = IDirect3DDevice9_Release(device);
17022 ok(!refcount, "Device has %u references left.\n", refcount);
17023 done:
17024 IDirect3D9_Release(d3d);
17025 DestroyWindow(window);
17028 static void volume_dxt5_test(void)
17030 IDirect3DVolumeTexture9 *texture;
17031 IDirect3DDevice9 *device;
17032 D3DLOCKED_BOX box;
17033 IDirect3D9 *d3d;
17034 unsigned int i;
17035 ULONG refcount;
17036 DWORD color;
17037 HWND window;
17038 HRESULT hr;
17040 static const char texture_data[] =
17042 /* A 8x4x2 texture consisting of 4 4x4 blocks. The colors of the blocks are red, green, blue and white. */
17043 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
17044 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
17045 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
17046 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
17048 static const struct
17050 struct vec3 position;
17051 struct vec3 texcrd;
17053 quads[] =
17055 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
17056 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
17057 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
17058 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
17060 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
17061 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
17062 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
17063 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
17065 static const DWORD expected_colors[] = {0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff};
17067 window = create_window();
17068 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17069 ok(!!d3d, "Failed to create a D3D object.\n");
17070 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17071 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_DXT5)))
17073 skip("DXT5 volume textures are not supported, skipping test.\n");
17074 goto done;
17076 if (!(device = create_device(d3d, window, window, TRUE)))
17078 skip("Failed to create a D3D device, skipping tests.\n");
17079 goto done;
17082 hr = IDirect3DDevice9_CreateVolumeTexture(device, 8, 4, 2, 1, 0, D3DFMT_DXT5,
17083 D3DPOOL_MANAGED, &texture, NULL);
17084 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
17086 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
17087 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
17088 memcpy(box.pBits, texture_data, sizeof(texture_data));
17089 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
17090 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
17092 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
17093 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
17094 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
17095 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17096 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17097 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17098 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
17099 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17100 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
17101 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17102 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
17103 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
17105 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
17106 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17107 hr = IDirect3DDevice9_BeginScene(device);
17108 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17109 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
17110 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17111 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
17112 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17113 hr = IDirect3DDevice9_EndScene(device);
17114 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17116 for (i = 0; i < 4; i++)
17118 color = getPixelColor(device, 80 + 160 * i, 240);
17119 ok (color_match(color, expected_colors[i], 1),
17120 "Expected color 0x%08x, got 0x%08x, case %u.\n", expected_colors[i], color, i);
17123 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17124 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17125 IDirect3DVolumeTexture9_Release(texture);
17126 refcount = IDirect3DDevice9_Release(device);
17127 ok(!refcount, "Device has %u references left.\n", refcount);
17128 done:
17129 IDirect3D9_Release(d3d);
17130 DestroyWindow(window);
17133 static void volume_v16u16_test(void)
17135 IDirect3DVolumeTexture9 *texture;
17136 IDirect3DPixelShader9 *shader;
17137 IDirect3DDevice9 *device;
17138 D3DLOCKED_BOX box;
17139 IDirect3D9 *d3d;
17140 unsigned int i;
17141 ULONG refcount;
17142 D3DCAPS9 caps;
17143 SHORT *texel;
17144 DWORD color;
17145 HWND window;
17146 HRESULT hr;
17148 static const struct
17150 struct vec3 position;
17151 struct vec3 texcrd;
17153 quads[] =
17155 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
17156 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
17157 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
17158 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
17160 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
17161 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
17162 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
17163 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
17165 static const DWORD shader_code[] =
17167 0xffff0101, /* ps_1_1 */
17168 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, */
17169 0x3f000000, 0x3f000000, /* 0.5, 0.5 */
17170 0x00000042, 0xb00f0000, /* tex t0 */
17171 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
17172 0x0000ffff /* end */
17175 window = create_window();
17176 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17177 ok(!!d3d, "Failed to create a D3D object.\n");
17178 if (!(device = create_device(d3d, window, window, TRUE)))
17180 skip("Failed to create a D3D device, skipping tests.\n");
17181 goto done;
17184 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17185 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17186 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
17188 skip("No ps_1_1 support, skipping tests.\n");
17189 IDirect3DDevice9_Release(device);
17190 goto done;
17192 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17193 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_V16U16)))
17195 skip("Volume V16U16 textures are not supported, skipping test.\n");
17196 IDirect3DDevice9_Release(device);
17197 goto done;
17200 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
17201 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
17202 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
17203 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
17204 hr = IDirect3DDevice9_SetPixelShader(device, shader);
17205 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
17206 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
17207 ok(SUCCEEDED(hr), "Failed to set filter, hr %#x.\n", hr);
17209 for (i = 0; i < 2; i++)
17211 D3DPOOL pool;
17213 if (i)
17214 pool = D3DPOOL_SYSTEMMEM;
17215 else
17216 pool = D3DPOOL_MANAGED;
17218 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
17219 pool, &texture, NULL);
17220 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
17222 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
17223 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
17225 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 0 * box.SlicePitch);
17226 texel[0] = 32767;
17227 texel[1] = 32767;
17228 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 0 * box.SlicePitch);
17229 texel[0] = -32768;
17230 texel[1] = 0;
17231 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 1 * box.SlicePitch);
17232 texel[0] = -16384;
17233 texel[1] = 16384;
17234 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 1 * box.SlicePitch);
17235 texel[0] = 0;
17236 texel[1] = 0;
17238 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
17239 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
17241 if (i)
17243 IDirect3DVolumeTexture9 *texture2;
17245 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
17246 D3DPOOL_DEFAULT, &texture2, NULL);
17247 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
17249 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture,
17250 (IDirect3DBaseTexture9 *)texture2);
17251 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17253 IDirect3DVolumeTexture9_Release(texture);
17254 texture = texture2;
17257 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
17258 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17260 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
17261 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17262 hr = IDirect3DDevice9_BeginScene(device);
17263 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17264 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
17265 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17266 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
17267 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17268 hr = IDirect3DDevice9_EndScene(device);
17269 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17271 color = getPixelColor(device, 120, 160);
17272 ok (color_match(color, 0x000080ff, 2),
17273 "Expected color 0x000080ff, got 0x%08x, V16U16 input -32768, 0.\n", color);
17274 color = getPixelColor(device, 120, 400);
17275 ok (color_match(color, 0x00ffffff, 2),
17276 "Expected color 0x00ffffff, got 0x%08x, V16U16 input 32767, 32767.\n", color);
17277 color = getPixelColor(device, 360, 160);
17278 ok (color_match(color, 0x007f7fff, 2),
17279 "Expected color 0x007f7fff, got 0x%08x, V16U16 input 0, 0.\n", color);
17280 color = getPixelColor(device, 360, 400);
17281 ok (color_match(color, 0x0040c0ff, 2),
17282 "Expected color 0x0040c0ff, got 0x%08x, V16U16 input -16384, 16384.\n", color);
17284 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17285 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17287 IDirect3DVolumeTexture9_Release(texture);
17290 IDirect3DPixelShader9_Release(shader);
17291 refcount = IDirect3DDevice9_Release(device);
17292 ok(!refcount, "Device has %u references left.\n", refcount);
17293 done:
17294 IDirect3D9_Release(d3d);
17295 DestroyWindow(window);
17298 static void add_dirty_rect_test_draw(IDirect3DDevice9 *device)
17300 HRESULT hr;
17301 static const struct
17303 struct vec3 position;
17304 struct vec2 texcoord;
17306 quad[] =
17308 {{-1.0, -1.0, 0.0}, {0.0, 0.0}},
17309 {{-1.0, 1.0, 0.0}, {0.0, 1.0}},
17310 {{ 1.0, -1.0, 0.0}, {1.0, 0.0}},
17311 {{ 1.0, 1.0, 0.0}, {1.0, 1.0}},
17314 hr = IDirect3DDevice9_BeginScene(device);
17315 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17316 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad, sizeof(*quad));
17317 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17318 hr = IDirect3DDevice9_EndScene(device);
17319 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17322 static void add_dirty_rect_test(void)
17324 HRESULT hr;
17325 IDirect3DTexture9 *tex_dst1, *tex_dst2, *tex_src_red, *tex_src_green,
17326 *tex_managed, *tex_dynamic;
17327 IDirect3DSurface9 *surface_dst2, *surface_src_green, *surface_src_red,
17328 *surface_managed, *surface_dynamic;
17329 IDirect3DDevice9 *device;
17330 IDirect3D9 *d3d;
17331 unsigned int i;
17332 ULONG refcount;
17333 DWORD *texel;
17334 HWND window;
17335 D3DLOCKED_RECT locked_rect;
17336 static const RECT part_rect = {96, 96, 160, 160};
17337 DWORD color;
17339 window = create_window();
17340 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17341 ok(!!d3d, "Failed to create a D3D object.\n");
17342 if (!(device = create_device(d3d, window, window, TRUE)))
17344 skip("Failed to create a D3D device, skipping tests.\n");
17345 IDirect3D9_Release(d3d);
17346 DestroyWindow(window);
17347 return;
17350 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17351 D3DPOOL_DEFAULT, &tex_dst1, NULL);
17352 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17353 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17354 D3DPOOL_DEFAULT, &tex_dst2, NULL);
17355 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17356 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17357 D3DPOOL_SYSTEMMEM, &tex_src_red, NULL);
17358 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17359 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17360 D3DPOOL_SYSTEMMEM, &tex_src_green, NULL);
17361 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17362 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17363 D3DPOOL_MANAGED, &tex_managed, NULL);
17364 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17365 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, D3DUSAGE_DYNAMIC,
17366 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex_dynamic, NULL);
17367 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17369 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dst2, 0, &surface_dst2);
17370 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17371 hr = IDirect3DTexture9_GetSurfaceLevel(tex_src_green, 0, &surface_src_green);
17372 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17373 hr = IDirect3DTexture9_GetSurfaceLevel(tex_src_red, 0, &surface_src_red);
17374 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17375 hr = IDirect3DTexture9_GetSurfaceLevel(tex_managed, 0, &surface_managed);
17376 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17377 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dynamic, 0, &surface_dynamic);
17378 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17380 fill_surface(surface_src_red, 0x00ff0000, 0);
17381 fill_surface(surface_src_green, 0x0000ff00, 0);
17383 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
17384 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
17385 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17386 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17387 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
17388 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17390 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17391 (IDirect3DBaseTexture9 *)tex_dst1);
17392 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17394 /* The second UpdateTexture call writing to tex_dst2 is ignored because tex_src_green is not dirty. */
17395 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_red,
17396 (IDirect3DBaseTexture9 *)tex_dst2);
17397 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17398 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17399 (IDirect3DBaseTexture9 *)tex_dst2);
17400 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17402 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst1);
17403 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17404 add_dirty_rect_test_draw(device);
17405 color = getPixelColor(device, 320, 240);
17406 ok(color_match(color, 0x0000ff00, 1),
17407 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17408 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17409 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17411 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst2);
17412 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17413 add_dirty_rect_test_draw(device);
17414 color = getPixelColor(device, 320, 240);
17415 todo_wine ok(color_match(color, 0x00ff0000, 1),
17416 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17417 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17418 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17420 /* AddDirtyRect on the destination is ignored. */
17421 hr = IDirect3DTexture9_AddDirtyRect(tex_dst2, &part_rect);
17422 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17423 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17424 (IDirect3DBaseTexture9 *)tex_dst2);
17425 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17426 add_dirty_rect_test_draw(device);
17427 color = getPixelColor(device, 320, 240);
17428 todo_wine ok(color_match(color, 0x00ff0000, 1),
17429 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17430 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17431 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17433 hr = IDirect3DTexture9_AddDirtyRect(tex_dst2, NULL);
17434 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17435 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17436 (IDirect3DBaseTexture9 *)tex_dst2);
17437 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17438 add_dirty_rect_test_draw(device);
17439 color = getPixelColor(device, 320, 240);
17440 todo_wine ok(color_match(color, 0x00ff0000, 1),
17441 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17442 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17443 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17445 /* AddDirtyRect on the source makes UpdateTexture work. Partial rectangle
17446 * tracking is supported. */
17447 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, &part_rect);
17448 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17449 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17450 (IDirect3DBaseTexture9 *)tex_dst2);
17451 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17452 add_dirty_rect_test_draw(device);
17453 color = getPixelColor(device, 320, 240);
17454 ok(color_match(color, 0x0000ff00, 1),
17455 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17456 color = getPixelColor(device, 1, 1);
17457 todo_wine ok(color_match(color, 0x00ff0000, 1),
17458 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17459 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17460 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17462 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, NULL);
17463 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17464 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17465 (IDirect3DBaseTexture9 *)tex_dst2);
17466 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17467 add_dirty_rect_test_draw(device);
17468 color = getPixelColor(device, 1, 1);
17469 ok(color_match(color, 0x0000ff00, 1),
17470 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17472 /* Locks with NO_DIRTY_UPDATE are ignored. */
17473 fill_surface(surface_src_green, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE);
17474 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17475 (IDirect3DBaseTexture9 *)tex_dst2);
17476 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17477 add_dirty_rect_test_draw(device);
17478 color = getPixelColor(device, 320, 240);
17479 todo_wine ok(color_match(color, 0x0000ff00, 1),
17480 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17481 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17482 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17484 /* Readonly maps write to D3DPOOL_SYSTEMMEM, but don't record a dirty rectangle. */
17485 fill_surface(surface_src_green, 0x000000ff, D3DLOCK_READONLY);
17486 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17487 (IDirect3DBaseTexture9 *)tex_dst2);
17488 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17489 add_dirty_rect_test_draw(device);
17490 color = getPixelColor(device, 320, 240);
17491 todo_wine ok(color_match(color, 0x0000ff00, 1),
17492 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17493 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17494 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17496 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, NULL);
17497 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17498 (IDirect3DBaseTexture9 *)tex_dst2);
17499 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17500 add_dirty_rect_test_draw(device);
17501 color = getPixelColor(device, 320, 240);
17502 ok(color_match(color, 0x000000ff, 1),
17503 "Expected color 0x000000ff, got 0x%08x.\n", color);
17504 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17505 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17507 /* Maps without either of these flags record a dirty rectangle. */
17508 fill_surface(surface_src_green, 0x00ffffff, 0);
17509 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17510 (IDirect3DBaseTexture9 *)tex_dst2);
17511 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17512 add_dirty_rect_test_draw(device);
17513 color = getPixelColor(device, 320, 240);
17514 ok(color_match(color, 0x00ffffff, 1),
17515 "Expected color 0x00ffffff, got 0x%08x.\n", color);
17516 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17517 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17519 /* Partial LockRect works just like a partial AddDirtyRect call. */
17520 hr = IDirect3DTexture9_LockRect(tex_src_green, 0, &locked_rect, &part_rect, 0);
17521 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17522 texel = locked_rect.pBits;
17523 for (i = 0; i < 64; i++)
17524 texel[i] = 0x00ff00ff;
17525 for (i = 1; i < 64; i++)
17526 memcpy((BYTE *)locked_rect.pBits + i * locked_rect.Pitch, locked_rect.pBits, locked_rect.Pitch);
17527 hr = IDirect3DTexture9_UnlockRect(tex_src_green, 0);
17528 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17529 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17530 (IDirect3DBaseTexture9 *)tex_dst2);
17531 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17532 add_dirty_rect_test_draw(device);
17533 color = getPixelColor(device, 320, 240);
17534 ok(color_match(color, 0x00ff00ff, 1),
17535 "Expected color 0x00ff00ff, got 0x%08x.\n", color);
17536 color = getPixelColor(device, 1, 1);
17537 ok(color_match(color, 0x00ffffff, 1),
17538 "Expected color 0x00ffffff, got 0x%08x.\n", color);
17539 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17540 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17542 fill_surface(surface_src_red, 0x00ff0000, 0);
17543 fill_surface(surface_src_green, 0x0000ff00, 0);
17545 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17546 (IDirect3DBaseTexture9 *)tex_dst1);
17547 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17548 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst1);
17549 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17550 add_dirty_rect_test_draw(device);
17551 color = getPixelColor(device, 320, 240);
17552 ok(color_match(color, 0x0000ff00, 1),
17553 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17554 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17555 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17557 /* UpdateSurface ignores the missing dirty marker. */
17558 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_red,
17559 (IDirect3DBaseTexture9 *)tex_dst2);
17560 hr = IDirect3DDevice9_UpdateSurface(device, surface_src_green, NULL, surface_dst2, NULL);
17561 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
17562 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst2);
17563 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17564 add_dirty_rect_test_draw(device);
17565 color = getPixelColor(device, 320, 240);
17566 ok(color_match(color, 0x0000ff00, 1),
17567 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17568 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17569 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17571 /* Tests with managed textures. */
17572 fill_surface(surface_managed, 0x00ff0000, 0);
17573 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_managed);
17574 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17575 add_dirty_rect_test_draw(device);
17576 color = getPixelColor(device, 320, 240);
17577 ok(color_match(color, 0x00ff0000, 1),
17578 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17579 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17580 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17582 /* Managed textures also honor D3DLOCK_NO_DIRTY_UPDATE. */
17583 fill_surface(surface_managed, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE);
17584 add_dirty_rect_test_draw(device);
17585 color = getPixelColor(device, 320, 240);
17586 ok(color_match(color, 0x00ff0000, 1),
17587 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17588 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17589 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17591 /* AddDirtyRect uploads the new contents.
17592 * Side note, not tested in the test: Partial surface updates work, and two separate
17593 * dirty rectangles are tracked individually. Tested on Nvidia Kepler, other drivers
17594 * untested. */
17595 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
17596 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17597 add_dirty_rect_test_draw(device);
17598 color = getPixelColor(device, 320, 240);
17599 ok(color_match(color, 0x0000ff00, 1),
17600 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17601 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17602 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17604 /* So does EvictManagedResources. */
17605 fill_surface(surface_managed, 0x000000ff, D3DLOCK_NO_DIRTY_UPDATE);
17606 hr = IDirect3DDevice9_EvictManagedResources(device);
17607 ok(SUCCEEDED(hr), "Failed to evict managed resources, hr %#x.\n", hr);
17608 add_dirty_rect_test_draw(device);
17609 color = getPixelColor(device, 320, 240);
17610 ok(color_match(color, 0x000000ff, 1),
17611 "Expected color 0x000000ff, got 0x%08x.\n", color);
17612 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17613 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17615 /* Tests with dynamic textures */
17616 fill_surface(surface_dynamic, 0x0000ffff, 0);
17617 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dynamic);
17618 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17619 add_dirty_rect_test_draw(device);
17620 color = getPixelColor(device, 320, 240);
17621 ok(color_match(color, 0x0000ffff, 1),
17622 "Expected color 0x0000ffff, got 0x%08x.\n", color);
17623 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17624 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17626 /* Dynamic textures don't honor D3DLOCK_NO_DIRTY_UPDATE. */
17627 fill_surface(surface_dynamic, 0x00ffff00, D3DLOCK_NO_DIRTY_UPDATE);
17628 add_dirty_rect_test_draw(device);
17629 color = getPixelColor(device, 320, 240);
17630 ok(color_match(color, 0x00ffff00, 1),
17631 "Expected color 0x00ffff00, 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 /* AddDirtyRect on a locked texture is allowed. */
17636 hr = IDirect3DTexture9_LockRect(tex_src_red, 0, &locked_rect, NULL, 0);
17637 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17638 hr = IDirect3DTexture9_AddDirtyRect(tex_src_red, NULL);
17639 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17640 hr = IDirect3DTexture9_UnlockRect(tex_src_red, 0);
17641 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17643 /* Redundant AddDirtyRect calls are ok. */
17644 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
17645 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17646 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
17647 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17649 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
17650 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17651 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
17652 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17653 IDirect3DSurface9_Release(surface_dst2);
17654 IDirect3DSurface9_Release(surface_managed);
17655 IDirect3DSurface9_Release(surface_src_red);
17656 IDirect3DSurface9_Release(surface_src_green);
17657 IDirect3DSurface9_Release(surface_dynamic);
17658 IDirect3DTexture9_Release(tex_src_red);
17659 IDirect3DTexture9_Release(tex_src_green);
17660 IDirect3DTexture9_Release(tex_dst1);
17661 IDirect3DTexture9_Release(tex_dst2);
17662 IDirect3DTexture9_Release(tex_managed);
17663 IDirect3DTexture9_Release(tex_dynamic);
17664 refcount = IDirect3DDevice9_Release(device);
17665 ok(!refcount, "Device has %u references left.\n", refcount);
17666 IDirect3D9_Release(d3d);
17667 DestroyWindow(window);
17670 static void test_per_stage_constant(void)
17672 IDirect3DDevice9 *device;
17673 IDirect3D9 *d3d;
17674 D3DCOLOR color;
17675 ULONG refcount;
17676 D3DCAPS9 caps;
17677 HWND window;
17678 HRESULT hr;
17680 static const struct
17682 struct vec3 position;
17683 D3DCOLOR diffuse;
17685 quad[] =
17687 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
17688 {{-1.0f, 1.0f, 0.1f}, 0xffff0000},
17689 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
17690 {{ 1.0f, 1.0f, 0.1f}, 0xffff0000},
17693 window = create_window();
17694 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17695 ok(!!d3d, "Failed to create a D3D object.\n");
17696 if (!(device = create_device(d3d, window, window, TRUE)))
17698 skip("Failed to create a D3D device, skipping tests.\n");
17699 goto done;
17702 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17703 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17704 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_PERSTAGECONSTANT))
17706 skip("Per-stage constants not supported, skipping tests.\n");
17707 IDirect3DDevice9_Release(device);
17708 goto done;
17711 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
17712 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
17713 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
17714 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17715 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
17716 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17717 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
17718 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17719 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
17720 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17722 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_CONSTANT, 0x80a1b2c3);
17723 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17724 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT);
17725 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17726 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17727 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17729 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17730 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17732 hr = IDirect3DDevice9_BeginScene(device);
17733 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17734 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17735 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17736 hr = IDirect3DDevice9_EndScene(device);
17737 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17739 color = getPixelColor(device, 320, 240);
17740 ok(color_match(color, 0x00a1b2c3, 1), "Got unexpected color 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 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT | D3DTA_COMPLEMENT);
17745 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17747 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17748 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17750 hr = IDirect3DDevice9_BeginScene(device);
17751 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17752 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17753 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17754 hr = IDirect3DDevice9_EndScene(device);
17755 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17757 color = getPixelColor(device, 320, 240);
17758 ok(color_match(color, 0x005e4d3c, 1), "Got unexpected color 0x%08x.\n", color);
17759 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17760 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17762 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT | D3DTA_ALPHAREPLICATE);
17763 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17765 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17766 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17768 hr = IDirect3DDevice9_BeginScene(device);
17769 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17770 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17771 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17772 hr = IDirect3DDevice9_EndScene(device);
17773 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17775 color = getPixelColor(device, 320, 240);
17776 ok(color_match(color, 0x00808080, 1), "Got unexpected color 0x%08x.\n", color);
17777 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17778 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17780 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_CONSTANT);
17781 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17782 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
17783 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17784 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CURRENT);
17785 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17787 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17788 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17790 hr = IDirect3DDevice9_BeginScene(device);
17791 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17792 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17793 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17794 hr = IDirect3DDevice9_EndScene(device);
17795 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17797 color = getPixelColor(device, 320, 240);
17798 ok(color_match(color, 0x0080007f, 1), "Got unexpected color 0x%08x.\n", color);
17799 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17800 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17802 refcount = IDirect3DDevice9_Release(device);
17803 ok(!refcount, "Device has %u references left.\n", refcount);
17804 done:
17805 IDirect3D9_Release(d3d);
17806 DestroyWindow(window);
17809 static void test_3dc_formats(void)
17811 static const char ati1n_data[] =
17813 /* A 4x4 texture with the color component at 50%. */
17814 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
17816 static const char ati2n_data[] =
17818 /* A 8x4 texture consisting of 2 4x4 blocks. The first block has 50% first color component,
17819 * 0% second component. Second block is the opposite. */
17820 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
17821 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
17823 static const struct
17825 struct vec3 position;
17826 struct vec2 texcoord;
17828 quads[] =
17830 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
17831 {{-1.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
17832 {{ 0.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
17833 {{ 0.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
17835 {{ 0.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
17836 {{ 0.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
17837 {{ 1.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
17838 {{ 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
17840 static const DWORD ati1n_fourcc = MAKEFOURCC('A','T','I','1');
17841 static const DWORD ati2n_fourcc = MAKEFOURCC('A','T','I','2');
17842 static const struct
17844 struct vec2 position;
17845 D3DCOLOR amd_r500;
17846 D3DCOLOR amd_r600;
17847 D3DCOLOR nvidia_old;
17848 D3DCOLOR nvidia_new;
17850 expected_colors[] =
17852 {{ 80, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
17853 {{240, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
17854 {{400, 240}, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff},
17855 {{560, 240}, 0x007f00ff, 0x007f00ff, 0x007f00ff, 0x007f00ff},
17857 IDirect3D9 *d3d;
17858 IDirect3DDevice9 *device;
17859 IDirect3DTexture9 *ati1n_texture, *ati2n_texture;
17860 D3DCAPS9 caps;
17861 D3DLOCKED_RECT rect;
17862 D3DCOLOR color;
17863 ULONG refcount;
17864 HWND window;
17865 HRESULT hr;
17866 unsigned int i;
17868 window = create_window();
17869 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17870 ok(!!d3d, "Failed to create a D3D object.\n");
17871 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17872 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati1n_fourcc)))
17874 skip("ATI1N textures are not supported, skipping test.\n");
17875 goto done;
17877 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17878 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati2n_fourcc)))
17880 skip("ATI2N textures are not supported, skipping test.\n");
17881 goto done;
17883 if (!(device = create_device(d3d, window, window, TRUE)))
17885 skip("Failed to create a D3D device, skipping tests.\n");
17886 goto done;
17888 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17889 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17890 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
17892 skip("D3DTA_TEMP not supported, skipping tests.\n");
17893 IDirect3DDevice9_Release(device);
17894 goto done;
17897 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, ati1n_fourcc,
17898 D3DPOOL_MANAGED, &ati1n_texture, NULL);
17899 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17901 hr = IDirect3DTexture9_LockRect(ati1n_texture, 0, &rect, NULL, 0);
17902 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17903 memcpy(rect.pBits, ati1n_data, sizeof(ati1n_data));
17904 hr = IDirect3DTexture9_UnlockRect(ati1n_texture, 0);
17905 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17907 hr = IDirect3DDevice9_CreateTexture(device, 8, 4, 1, 0, ati2n_fourcc,
17908 D3DPOOL_MANAGED, &ati2n_texture, NULL);
17909 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17911 hr = IDirect3DTexture9_LockRect(ati2n_texture, 0, &rect, NULL, 0);
17912 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17913 memcpy(rect.pBits, ati2n_data, sizeof(ati2n_data));
17914 hr = IDirect3DTexture9_UnlockRect(ati2n_texture, 0);
17915 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17917 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0));
17918 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
17919 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
17920 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17921 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
17922 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17923 /* The temporary register is initialized to 0. */
17924 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TEMP);
17925 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17926 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
17927 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#x.\n", hr);
17928 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
17929 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#x.\n", hr);
17930 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
17931 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17932 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
17933 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
17935 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
17936 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17937 hr = IDirect3DDevice9_BeginScene(device);
17938 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17939 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)ati1n_texture);
17940 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17941 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
17942 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17943 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)ati2n_texture);
17944 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17945 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
17946 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17947 hr = IDirect3DDevice9_EndScene(device);
17948 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17950 for (i = 0; i < 4; ++i)
17952 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
17953 ok (color_match(color, expected_colors[i].amd_r500, 1)
17954 || color_match(color, expected_colors[i].amd_r600, 1)
17955 || color_match(color, expected_colors[i].nvidia_old, 1)
17956 || color_match(color, expected_colors[i].nvidia_new, 1),
17957 "Got unexpected color 0x%08x, case %u.\n", color, i);
17960 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17961 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17962 IDirect3DTexture9_Release(ati2n_texture);
17963 IDirect3DTexture9_Release(ati1n_texture);
17964 refcount = IDirect3DDevice9_Release(device);
17965 ok(!refcount, "Device has %u references left.\n", refcount);
17967 done:
17968 IDirect3D9_Release(d3d);
17969 DestroyWindow(window);
17972 static void test_fog_interpolation(void)
17974 HRESULT hr;
17975 IDirect3DDevice9 *device;
17976 IDirect3D9 *d3d;
17977 ULONG refcount;
17978 HWND window;
17979 D3DCOLOR color;
17980 static const struct
17982 struct vec3 position;
17983 D3DCOLOR diffuse;
17984 D3DCOLOR specular;
17986 quad[] =
17988 {{-1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff000000},
17989 {{-1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff000000},
17990 {{ 1.0f, -1.0f, 1.0f}, 0xffff0000, 0x00000000},
17991 {{ 1.0f, 1.0f, 1.0f}, 0xffff0000, 0x00000000},
17993 union
17995 DWORD d;
17996 float f;
17997 } conv;
17998 unsigned int i;
17999 static const struct
18001 D3DFOGMODE vfog, tfog;
18002 D3DSHADEMODE shade;
18003 D3DCOLOR middle_color;
18004 BOOL todo;
18006 tests[] =
18008 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, FALSE},
18009 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, FALSE},
18010 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, TRUE},
18011 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, TRUE},
18012 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
18013 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
18014 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
18015 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
18017 static const D3DMATRIX ident_mat =
18019 1.0f, 0.0f, 0.0f, 0.0f,
18020 0.0f, 1.0f, 0.0f, 0.0f,
18021 0.0f, 0.0f, 1.0f, 0.0f,
18022 0.0f, 0.0f, 0.0f, 1.0f
18023 }}};
18024 D3DCAPS9 caps;
18026 window = create_window();
18027 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18028 ok(!!d3d, "Failed to create a D3D object.\n");
18030 if (!(device = create_device(d3d, window, window, TRUE)))
18032 skip("Failed to create a D3D device, skipping tests.\n");
18033 IDirect3D9_Release(d3d);
18034 DestroyWindow(window);
18035 return;
18038 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18039 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18040 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
18041 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
18043 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
18044 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
18045 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18046 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18047 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
18048 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18049 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
18050 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18051 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
18052 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18053 conv.f = 5.0;
18054 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGDENSITY, conv.d);
18055 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18057 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
18058 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
18059 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
18060 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
18061 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x000000ff);
18062 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18064 /* Some of the tests seem to depend on the projection matrix explicitly
18065 * being set to an identity matrix, even though that's the default.
18066 * (AMD Radeon X1600, AMD Radeon HD 6310, Windows 7). Without this,
18067 * the drivers seem to use a static z = 1.0 input for the fog equation.
18068 * The input value is independent of the actual z and w component of
18069 * the vertex position. */
18070 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
18071 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
18073 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
18075 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
18076 continue;
18078 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00808080, 0.0f, 0);
18079 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18081 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shade);
18082 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18083 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
18084 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18085 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
18086 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18087 hr = IDirect3DDevice9_BeginScene(device);
18088 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18089 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18090 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18091 hr = IDirect3DDevice9_EndScene(device);
18092 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18094 color = getPixelColor(device, 0, 240);
18095 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
18096 color = getPixelColor(device, 320, 240);
18097 todo_wine_if (tests[i].todo)
18098 ok(color_match(color, tests[i].middle_color, 2),
18099 "Got unexpected color 0x%08x, case %u.\n", color, i);
18100 color = getPixelColor(device, 639, 240);
18101 ok(color_match(color, 0x0000fd02, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
18102 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18103 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18106 refcount = IDirect3DDevice9_Release(device);
18107 ok(!refcount, "Device has %u references left.\n", refcount);
18108 IDirect3D9_Release(d3d);
18109 DestroyWindow(window);
18112 static void test_negative_fixedfunction_fog(void)
18114 HRESULT hr;
18115 IDirect3DDevice9 *device;
18116 IDirect3D9 *d3d;
18117 ULONG refcount;
18118 HWND window;
18119 D3DCOLOR color;
18120 static const struct
18122 struct vec3 position;
18123 D3DCOLOR diffuse;
18125 quad[] =
18127 {{-1.0f, -1.0f, -0.5f}, 0xffff0000},
18128 {{-1.0f, 1.0f, -0.5f}, 0xffff0000},
18129 {{ 1.0f, -1.0f, -0.5f}, 0xffff0000},
18130 {{ 1.0f, 1.0f, -0.5f}, 0xffff0000},
18132 static const struct
18134 struct vec4 position;
18135 D3DCOLOR diffuse;
18137 tquad[] =
18139 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
18140 {{640.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
18141 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
18142 {{640.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
18144 unsigned int i;
18145 static const D3DMATRIX zero =
18147 1.0f, 0.0f, 0.0f, 0.0f,
18148 0.0f, 1.0f, 0.0f, 0.0f,
18149 0.0f, 0.0f, 0.0f, 0.0f,
18150 0.0f, 0.0f, 0.0f, 1.0f
18151 }}};
18152 /* Needed to make AMD drivers happy. Yeah, it is not supposed to
18153 * have an effect on RHW draws. */
18154 static const D3DMATRIX identity =
18156 1.0f, 0.0f, 0.0f, 0.0f,
18157 0.0f, 1.0f, 0.0f, 0.0f,
18158 0.0f, 0.0f, 1.0f, 0.0f,
18159 0.0f, 0.0f, 0.0f, 1.0f
18160 }}};
18161 static const struct
18163 DWORD pos_type;
18164 const void *quad;
18165 size_t stride;
18166 const D3DMATRIX *matrix;
18167 union
18169 float f;
18170 DWORD d;
18171 } start, end;
18172 D3DFOGMODE vfog, tfog;
18173 DWORD color, color_broken, color_broken2;
18175 tests[] =
18177 /* Run the XYZRHW tests first. Depth clamping is broken after RHW draws on the testbot.
18179 * Geforce8+ GPUs on Windows abs() table fog, everything else does not. */
18180 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, { 0.0f}, {1.0f},
18181 D3DFOG_NONE, D3DFOG_LINEAR, 0x00ff0000, 0x00808000, 0x00808000},
18182 /* r200 GPUs and presumably all d3d8 and older HW clamp the fog
18183 * parameters to 0.0 and 1.0 in the table fog case. */
18184 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, {-1.0f}, {0.0f},
18185 D3DFOG_NONE, D3DFOG_LINEAR, 0x00808000, 0x00ff0000, 0x0000ff00},
18186 /* test_fog_interpolation shows that vertex fog evaluates the fog
18187 * equation in the vertex pipeline. Start = -1.0 && end = 0.0 shows
18188 * that the abs happens before the fog equation is evaluated.
18190 * Vertex fog abs() behavior is the same on all GPUs. */
18191 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
18192 D3DFOG_LINEAR, D3DFOG_NONE, 0x00808000, 0x00808000, 0x00808000},
18193 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, {-1.0f}, {0.0f},
18194 D3DFOG_LINEAR, D3DFOG_NONE, 0x0000ff00, 0x0000ff00, 0x0000ff00},
18195 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
18196 D3DFOG_EXP, D3DFOG_NONE, 0x009b6400, 0x009b6400, 0x009b6400},
18198 D3DCAPS9 caps;
18200 window = create_window();
18201 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18202 ok(!!d3d, "Failed to create a D3D object.\n");
18204 if (!(device = create_device(d3d, window, window, TRUE)))
18206 skip("Failed to create a D3D device, skipping tests.\n");
18207 IDirect3D9_Release(d3d);
18208 DestroyWindow(window);
18209 return;
18212 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18213 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18214 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
18215 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests.\n");
18217 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18218 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18219 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
18220 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18221 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
18222 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18223 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
18224 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18225 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
18226 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
18228 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
18230 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
18231 continue;
18233 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
18234 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18236 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, tests[i].matrix);
18237 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
18238 hr = IDirect3DDevice9_SetFVF(device, tests[i].pos_type | D3DFVF_DIFFUSE);
18239 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
18240 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, tests[i].start.d);
18241 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18242 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, tests[i].end.d);
18243 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18244 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
18245 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18246 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
18247 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18249 hr = IDirect3DDevice9_BeginScene(device);
18250 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18251 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tests[i].quad, tests[i].stride);
18252 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18253 hr = IDirect3DDevice9_EndScene(device);
18254 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18256 color = getPixelColor(device, 320, 240);
18257 ok(color_match(color, tests[i].color, 2) || broken(color_match(color, tests[i].color_broken, 2))
18258 || broken(color_match(color, tests[i].color_broken2, 2)),
18259 "Got unexpected color 0x%08x, case %u.\n", color, i);
18260 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18261 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18264 refcount = IDirect3DDevice9_Release(device);
18265 ok(!refcount, "Device has %u references left.\n", refcount);
18266 IDirect3D9_Release(d3d);
18267 DestroyWindow(window);
18270 static void test_position_index(void)
18272 static const D3DVERTEXELEMENT9 decl_elements[] =
18274 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
18275 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 1},
18276 D3DDECL_END()
18278 /* Declaring (and using) a position1 output semantic in a VS fails at draw time on AMD
18279 * but works on Nvidia.
18280 * MSDN is not consistent on this point. */
18281 static const DWORD vs_code[] =
18283 0xfffe0300, /* vs_3_0 */
18284 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
18285 0x0200001f, 0x80010000, 0x900f0001, /* dcl_position1 v1 */
18286 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position0 o0 */
18287 0x0200001f, 0x80010000, 0xe00f0001, /* dcl_position1 o1 */
18288 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
18289 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
18290 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
18291 0x02000001, 0xe00f0002, 0x90e40001, /* mov o2, v1 */
18292 0x0000ffff /* end */
18294 static const DWORD vs_code_2[] =
18296 0xfffe0300, /* vs_3_0 */
18297 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
18298 0x0200001f, 0x80010000, 0x900f0001, /* dcl_position1 v1 */
18299 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position0 o0 */
18300 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
18301 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
18302 0x02000001, 0xe00f0002, 0x90e40001, /* mov o2, v1 */
18303 0x0000ffff /* end */
18305 static const DWORD ps_code[] =
18307 0xffff0300, /* ps_3_0 */
18308 0x0200001f, 0x80010000, 0x900f0000, /* dcl_position1 v0 */
18309 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
18310 0x0000ffff /* end */
18312 static const DWORD ps_code_2[] =
18314 0xffff0300, /* ps_3_0 */
18315 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
18316 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
18317 0x0000ffff /* end */
18319 /* This one is considered invalid by the native shader assembler. */
18320 static const DWORD ps_code_bad[] =
18322 0xffff0300, /* ps_3_0 */
18323 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
18324 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
18325 0x0000ffff /* end */
18327 static const struct
18329 struct vec3 position;
18330 struct vec3 position1;
18332 quad[] =
18334 {{-1.0f, -1.0f, 0.5f}, {1.0f, 0.0f, 0.0f}},
18335 {{-1.0f, 1.0f, 0.5f}, {1.0f, 0.0f, 0.0f}},
18336 {{ 1.0f, -1.0f, 0.5f}, {0.0f, 1.0f, 0.0f}},
18337 {{ 1.0f, 1.0f, 0.5f}, {0.0f, 1.0f, 0.0f}},
18339 static const struct
18341 struct vec2 position;
18342 D3DCOLOR expected_color;
18343 D3DCOLOR broken_color;
18345 expected_colors[] =
18347 {{ 80, 240}, 0x00df2000, 0x00ff00ff},
18348 {{240, 240}, 0x009f6000, 0x00ff00ff},
18349 {{400, 240}, 0x00609f00, 0x00ff00ff},
18350 {{560, 240}, 0x0020df00, 0x00ff00ff},
18352 IDirect3D9 *d3d;
18353 IDirect3DDevice9 *device;
18354 IDirect3DVertexDeclaration9 *vertex_declaration;
18355 IDirect3DVertexShader9 *vs, *vs2;
18356 IDirect3DPixelShader9 *ps, *ps2;
18357 D3DCAPS9 caps;
18358 D3DCOLOR color;
18359 ULONG refcount;
18360 HWND window;
18361 HRESULT hr;
18362 unsigned int i;
18364 window = create_window();
18365 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18366 ok(!!d3d, "Failed to create a D3D object.\n");
18367 if (!(device = create_device(d3d, window, window, TRUE)))
18369 skip("Failed to create a D3D device, skipping tests.\n");
18370 goto done;
18373 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18374 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18375 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0)
18376 || caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
18378 skip("Shader model 3.0 unsupported, skipping tests.\n");
18379 IDirect3DDevice9_Release(device);
18380 goto done;
18383 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
18384 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed, hr %#x\n", hr);
18386 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
18387 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x\n", hr);
18389 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
18390 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
18391 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code_2, &vs2);
18392 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
18394 hr = IDirect3DDevice9_SetVertexShader(device, vs);
18395 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
18397 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_bad, &ps);
18398 ok(hr == D3DERR_INVALIDCALL, "CreatePixelShader returned hr %#x.\n", hr);
18400 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
18401 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
18402 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_2, &ps2);
18403 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
18405 hr = IDirect3DDevice9_SetPixelShader(device, ps);
18406 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18408 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
18409 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18410 hr = IDirect3DDevice9_BeginScene(device);
18411 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18412 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18413 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18414 hr = IDirect3DDevice9_EndScene(device);
18415 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18417 for (i = 0; i < sizeof(expected_colors) / sizeof(expected_colors[0]); ++i)
18419 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
18420 ok (color_match(color, expected_colors[i].expected_color, 1)
18421 || broken(color_match(color, expected_colors[i].broken_color, 1)),
18422 "Got unexpected color 0x%08x, case %u.\n", color, i);
18425 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
18426 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18428 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
18429 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18430 hr = IDirect3DDevice9_BeginScene(device);
18431 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18432 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18433 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18434 hr = IDirect3DDevice9_EndScene(device);
18435 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18437 for (i = 0; i < sizeof(expected_colors) / sizeof(expected_colors[0]); ++i)
18439 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
18440 ok (color_match(color, expected_colors[i].expected_color, 1)
18441 || broken(color_match(color, expected_colors[i].broken_color, 1)),
18442 "Got unexpected color 0x%08x, case %u.\n", color, i);
18445 hr = IDirect3DDevice9_SetVertexShader(device, vs2);
18446 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
18448 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
18449 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18450 hr = IDirect3DDevice9_BeginScene(device);
18451 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18452 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18453 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18454 hr = IDirect3DDevice9_EndScene(device);
18455 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18457 for (i = 0; i < sizeof(expected_colors) / sizeof(expected_colors[0]); ++i)
18459 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
18460 ok (color_match(color, expected_colors[i].expected_color, 1),
18461 "Got unexpected color 0x%08x, case %u.\n", color, i);
18464 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18465 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18467 IDirect3DPixelShader9_Release(ps2);
18468 IDirect3DPixelShader9_Release(ps);
18469 IDirect3DVertexShader9_Release(vs2);
18470 IDirect3DVertexShader9_Release(vs);
18471 IDirect3DVertexDeclaration9_Release(vertex_declaration);
18472 refcount = IDirect3DDevice9_Release(device);
18473 ok(!refcount, "Device has %u references left.\n", refcount);
18475 done:
18476 IDirect3D9_Release(d3d);
18477 DestroyWindow(window);
18480 static void test_table_fog_zw(void)
18482 HRESULT hr;
18483 IDirect3DDevice9 *device;
18484 IDirect3D9 *d3d;
18485 ULONG refcount;
18486 HWND window;
18487 D3DCOLOR color;
18488 D3DCAPS9 caps;
18489 static struct
18491 struct vec4 position;
18492 D3DCOLOR diffuse;
18494 quad[] =
18496 {{ 0.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
18497 {{640.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
18498 {{ 0.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
18499 {{640.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
18501 static const D3DMATRIX identity =
18503 1.0f, 0.0f, 0.0f, 0.0f,
18504 0.0f, 1.0f, 0.0f, 0.0f,
18505 0.0f, 0.0f, 1.0f, 0.0f,
18506 0.0f, 0.0f, 0.0f, 1.0f
18507 }}};
18508 static const struct
18510 float z, w;
18511 D3DZBUFFERTYPE z_test;
18512 D3DCOLOR color;
18514 tests[] =
18516 {0.7f, 0.0f, D3DZB_TRUE, 0x004cb200},
18517 {0.7f, 0.0f, D3DZB_FALSE, 0x004cb200},
18518 {0.7f, 0.3f, D3DZB_TRUE, 0x004cb200},
18519 {0.7f, 0.3f, D3DZB_FALSE, 0x004cb200},
18520 {0.7f, 3.0f, D3DZB_TRUE, 0x004cb200},
18521 {0.7f, 3.0f, D3DZB_FALSE, 0x004cb200},
18522 {0.3f, 0.0f, D3DZB_TRUE, 0x00b24c00},
18523 {0.3f, 0.0f, D3DZB_FALSE, 0x00b24c00},
18525 unsigned int i;
18527 window = create_window();
18528 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18529 ok(!!d3d, "Failed to create a D3D object.\n");
18531 if (!(device = create_device(d3d, window, window, TRUE)))
18533 skip("Failed to create a D3D device, skipping tests.\n");
18534 IDirect3D9_Release(d3d);
18535 DestroyWindow(window);
18536 return;
18539 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18540 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18541 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
18543 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping POSITIONT table fog test.\n");
18544 goto done;
18547 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18548 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18549 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
18550 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18551 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
18552 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18553 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
18554 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
18555 /* Work around an AMD Windows driver bug. Needs a proj matrix applied redundantly. */
18556 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
18557 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
18558 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
18559 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18560 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
18561 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
18563 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
18565 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
18566 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18568 quad[0].position.z = tests[i].z;
18569 quad[1].position.z = tests[i].z;
18570 quad[2].position.z = tests[i].z;
18571 quad[3].position.z = tests[i].z;
18572 quad[0].position.w = tests[i].w;
18573 quad[1].position.w = tests[i].w;
18574 quad[2].position.w = tests[i].w;
18575 quad[3].position.w = tests[i].w;
18576 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, tests[i].z_test);
18577 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18579 hr = IDirect3DDevice9_BeginScene(device);
18580 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18581 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
18582 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18583 hr = IDirect3DDevice9_EndScene(device);
18584 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18586 color = getPixelColor(device, 320, 240);
18587 ok(color_match(color, tests[i].color, 2),
18588 "Got unexpected color 0x%08x, expected 0x%08x, case %u.\n", color, tests[i].color, i);
18589 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18590 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18593 done:
18594 refcount = IDirect3DDevice9_Release(device);
18595 ok(!refcount, "Device has %u references left.\n", refcount);
18596 IDirect3D9_Release(d3d);
18597 DestroyWindow(window);
18600 static void test_signed_formats(void)
18602 IDirect3DDevice9 *device;
18603 HWND window;
18604 HRESULT hr;
18605 unsigned int i, j, x, y;
18606 IDirect3DTexture9 *texture, *texture_sysmem;
18607 IDirect3DSurface9 *src_surface, *dst_surface;
18608 D3DLOCKED_RECT locked_rect;
18609 IDirect3DPixelShader9 *shader, *shader_alpha;
18610 IDirect3D9 *d3d;
18611 D3DCOLOR color;
18612 D3DCAPS9 caps;
18613 ULONG refcount;
18615 /* The input data was designed for D3DFMT_L6V5U5 and then transferred
18616 * to the other formats because L6V5U5 is the lowest precision format.
18617 * It tests the extreme values -1.0 (-16) and 1.0 (15) for U/V and
18618 * 0.0 (0) and 1.0 (63) for L, the neutral point 0 as well as -1 and 1.
18619 * Some other intermediate values are tested too. The input value -15
18620 * (min + 1) is tested as well. Unlike what OpenGL 4.4 says in section
18621 * 2.3.4.1, this value does not represent -1.0. In the interest of re-
18622 * using the expected output data the 8 bit and 16 bit values in V8U8
18623 * and V16U16 match (post-normalization) the 5 bit input values. Thus
18624 * -1, 1 and -127 are not tested in V8U8.
18626 * 8 bit specific values like -127 are tested in the Q channel of
18627 * D3DFMT_Q8W8V8U8. Here d3d seems to follow the rules from the GL
18628 * spec. AMD's r200 is broken though and returns a value < -1.0 for
18629 * -128. The difference between using -127 or -128 as the lowest
18630 * possible value gets lost in the slop of 1 though. */
18631 static const USHORT content_v8u8[4][4] =
18633 {0x0000, 0x7f7f, 0x8880, 0x0000},
18634 {0x0080, 0x8000, 0x7f00, 0x007f},
18635 {0x193b, 0xe8c8, 0x0808, 0xf8f8},
18636 {0x4444, 0xc0c0, 0xa066, 0x22e0},
18638 static const DWORD content_v16u16[4][4] =
18640 {0x00000000, 0x7fff7fff, 0x88008000, 0x00000000},
18641 {0x00008000, 0x80000000, 0x7fff0000, 0x00007fff},
18642 {0x19993bbb, 0xe800c800, 0x08880888, 0xf800f800},
18643 {0x44444444, 0xc000c000, 0xa0006666, 0x2222e000},
18645 static const DWORD content_q8w8v8u8[4][4] =
18647 {0x00000000, 0xff7f7f7f, 0x7f008880, 0x817f0000},
18648 {0x10000080, 0x20008000, 0x30007f00, 0x4000007f},
18649 {0x5020193b, 0x6028e8c8, 0x70020808, 0x807ff8f8},
18650 {0x90414444, 0xa000c0c0, 0x8261a066, 0x834922e0},
18652 static const DWORD content_x8l8v8u8[4][4] =
18654 {0x00000000, 0x00ff7f7f, 0x00008880, 0x00ff0000},
18655 {0x00000080, 0x00008000, 0x00007f00, 0x0000007f},
18656 {0x0041193b, 0x0051e8c8, 0x00040808, 0x00fff8f8},
18657 {0x00824444, 0x0000c0c0, 0x00c2a066, 0x009222e0},
18659 /* D3DFMT_L6V5U5 has poor precision on some GPUs. On a GeForce 7 the highest V and U value (15)
18660 * results in the output color 0xfb, which is 4 steps away from the correct value 0xff. It is
18661 * not the ~0xf0 you'd get if you blindly left-shifted the 5 bit value to form an 8 bit value
18662 * though.
18664 * There may also be an off-by-one bug involved: The value -7 should result in the output 0x47,
18665 * but ends up as 0x4d. Likewise, -3 becomes 0x6e instead of 0x67. Those values are close to
18666 * the proper results of -6 and -2.
18668 * On Wine the emulation with unsigned R5G6B5 has poor precision, e.g. the signed 0 becomes 16,
18669 * and ((16 / 31) - 0.5) * 2.0 is 0.032 instead of 0.000. The final output result we read back
18670 * is 0x84 instead of 0x80. */
18671 static const USHORT content_l6v5u5[4][4] =
18673 {0x0000, 0xfdef, 0x0230, 0xfc00},
18674 {0x0010, 0x0200, 0x01e0, 0x000f},
18675 {0x4067, 0x53b9, 0x0421, 0xffff},
18676 {0x8108, 0x0318, 0xc28c, 0x909c},
18678 static const struct
18680 D3DFORMAT format;
18681 const char *name;
18682 const void *content;
18683 SIZE_T pixel_size;
18684 BOOL blue, alpha;
18685 unsigned int slop, slop_broken, alpha_broken;
18687 formats[] =
18689 {D3DFMT_V8U8, "D3DFMT_V8U8", content_v8u8, sizeof(WORD), FALSE, FALSE, 1, 0, FALSE},
18690 {D3DFMT_V16U16, "D3DFMT_V16U16", content_v16u16, sizeof(DWORD), FALSE, FALSE, 1, 0, FALSE},
18691 {D3DFMT_Q8W8V8U8, "D3DFMT_Q8W8V8U8", content_q8w8v8u8, sizeof(DWORD), TRUE, TRUE, 1, 0, TRUE },
18692 {D3DFMT_X8L8V8U8, "D3DFMT_X8L8V8U8", content_x8l8v8u8, sizeof(DWORD), TRUE, FALSE, 1, 0, FALSE},
18693 {D3DFMT_L6V5U5, "D3DFMT_L6V5U5", content_l6v5u5, sizeof(WORD), TRUE, FALSE, 4, 7, FALSE},
18695 static const struct
18697 D3DPOOL pool;
18698 UINT width;
18699 RECT src_rect;
18700 POINT dst_point;
18702 tests[] =
18704 {D3DPOOL_SYSTEMMEM, 4, {1, 1, 2, 3}, {2, 0}},
18705 {D3DPOOL_SYSTEMMEM, 1, {0, 1, 1, 3}, {0, 0}},
18706 {D3DPOOL_MANAGED, 4, {1, 1, 2, 3}, {2, 0}},
18707 {D3DPOOL_MANAGED, 1, {0, 1, 1, 3}, {0, 0}},
18709 static const DWORD shader_code[] =
18711 0xffff0101, /* ps_1_1 */
18712 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0,5, 0,5 */
18713 0x00000042, 0xb00f0000, /* tex t0 */
18714 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
18715 0x0000ffff /* end */
18717 static const DWORD shader_code_alpha[] =
18719 /* The idea of this shader is to replicate the alpha value in .rg, and set
18720 * blue to 1.0 iff the alpha value is < -1.0 and 0.0 otherwise. */
18721 0xffff0101, /* ps_1_1 */
18722 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
18723 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
18724 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
18725 0x00000042, 0xb00f0000, /* tex t0 */
18726 0x00000004, 0x80070000, 0xb0ff0000, 0xa0e40000, 0xa0e40000, /* mad r0.rgb, t0.a, c0, c0 */
18727 0x00000003, 0x80080000, 0xb1ff0000, 0xa0e40000, /* sub r0.a, -t0.a, c0 */
18728 0x00000050, 0x80080000, 0x80ff0000, 0xa0ff0001, 0xa0ff0002, /* cnd r0.a, r0.a, c1.a, c2.a */
18729 0x00000005, 0x80070001, 0xa0e40001, 0x80e40000, /* mul r1.rgb, c1, r0 */
18730 0x00000004, 0x80070000, 0x80ff0000, 0xa0e40002, 0x80e40001, /* mad r0.rgb, r0.a, c2, r1 */
18731 0x0000ffff /* end */
18733 static const struct
18735 struct vec3 position;
18736 struct vec2 texcrd;
18738 quad[] =
18740 /* Flip the y coordinate to make the input and
18741 * output arrays easier to compare. */
18742 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 1.0f}},
18743 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 0.0f}},
18744 {{ 1.0f, -1.0f, 0.0f}, { 1.0f, 1.0f}},
18745 {{ 1.0f, 1.0f, 0.0f}, { 1.0f, 0.0f}},
18747 static const D3DCOLOR expected_alpha[4][4] =
18749 {0x00808000, 0x007f7f00, 0x00ffff00, 0x00000000},
18750 {0x00909000, 0x00a0a000, 0x00b0b000, 0x00c0c000},
18751 {0x00d0d000, 0x00e0e000, 0x00f0f000, 0x00000000},
18752 {0x00101000, 0x00202000, 0x00010100, 0x00020200},
18754 static const BOOL alpha_broken[4][4] =
18756 {FALSE, FALSE, FALSE, FALSE},
18757 {FALSE, FALSE, FALSE, FALSE},
18758 {FALSE, FALSE, FALSE, TRUE },
18759 {FALSE, FALSE, FALSE, FALSE},
18761 static const D3DCOLOR expected_colors[4][4] =
18763 {0x00808080, 0x00fefeff, 0x00010780, 0x008080ff},
18764 {0x00018080, 0x00800180, 0x0080fe80, 0x00fe8080},
18765 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
18766 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
18768 static const D3DCOLOR expected_colors2[4][4] =
18770 {0x00808080, 0x00fefeff, 0x00800180, 0x008080ff},
18771 {0x00018080, 0x00800180, 0x004767a8, 0x00fe8080},
18772 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
18773 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
18775 static const D3DCOLOR expected_colors3[4] =
18777 0x00018080,
18778 0x00ba98a0,
18779 0x00ba98a0,
18780 0x00c3c3c0,
18782 D3DCOLOR expected_color;
18784 window = create_window();
18785 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18786 ok(!!d3d, "Failed to create a D3D object.\n");
18788 if (!(device = create_device(d3d, window, window, TRUE)))
18790 skip("Failed to create a D3D device, skipping tests.\n");
18791 IDirect3D9_Release(d3d);
18792 DestroyWindow(window);
18793 return;
18796 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18797 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18799 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
18801 skip("Pixel shaders not supported, skipping converted format test.\n");
18802 goto done;
18805 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
18806 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18807 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
18808 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
18809 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
18810 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
18811 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_alpha, &shader_alpha);
18812 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
18814 for (i = 0; i < sizeof(formats) / sizeof(*formats); i++)
18816 hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
18817 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, formats[i].format);
18818 if (FAILED(hr))
18820 skip("Format %s not supported, skipping.\n", formats[i].name);
18821 continue;
18824 for (j = 0; j < sizeof(tests) / sizeof(*tests); j++)
18826 texture_sysmem = NULL;
18827 hr = IDirect3DDevice9_CreateTexture(device, tests[j].width, 4, 1, 0,
18828 formats[i].format, tests[j].pool, &texture, NULL);
18829 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
18831 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
18832 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
18833 for (y = 0; y < 4; y++)
18835 memcpy((char *)locked_rect.pBits + y * locked_rect.Pitch,
18836 (char *)formats[i].content + y * 4 * formats[i].pixel_size,
18837 tests[j].width * formats[i].pixel_size);
18839 hr = IDirect3DTexture9_UnlockRect(texture, 0);
18840 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
18842 if (tests[j].pool == D3DPOOL_SYSTEMMEM)
18844 texture_sysmem = texture;
18845 hr = IDirect3DDevice9_CreateTexture(device, tests[j].width, 4, 1, 0,
18846 formats[i].format, D3DPOOL_DEFAULT, &texture, NULL);
18847 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
18849 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture_sysmem,
18850 (IDirect3DBaseTexture9 *)texture);
18851 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
18854 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
18855 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
18856 hr = IDirect3DDevice9_SetPixelShader(device, shader_alpha);
18857 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18859 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
18860 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18861 hr = IDirect3DDevice9_BeginScene(device);
18862 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18863 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
18864 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18865 hr = IDirect3DDevice9_EndScene(device);
18866 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18868 for (y = 0; y < 4; y++)
18870 for (x = 0; x < tests[j].width; x++)
18872 BOOL r200_broken = formats[i].alpha_broken && alpha_broken[y][x];
18873 if (formats[i].alpha)
18874 expected_color = expected_alpha[y][x];
18875 else
18876 expected_color = 0x00ffff00;
18878 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
18879 ok(color_match(color, expected_color, 1) || broken(r200_broken),
18880 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
18881 expected_color, color, formats[i].name, x, y);
18884 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18885 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18887 hr = IDirect3DDevice9_SetPixelShader(device, shader);
18888 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18890 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
18891 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18892 hr = IDirect3DDevice9_BeginScene(device);
18893 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18894 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
18895 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18896 hr = IDirect3DDevice9_EndScene(device);
18897 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18899 for (y = 0; y < 4; y++)
18901 for (x = 0; x < tests[j].width; x++)
18903 expected_color = expected_colors[y][x];
18904 if (!formats[i].blue)
18905 expected_color |= 0x000000ff;
18907 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
18908 ok(color_match(color, expected_color, formats[i].slop)
18909 || broken(color_match(color, expected_color, formats[i].slop_broken)),
18910 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
18911 expected_color, color, formats[i].name, x, y);
18914 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18915 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18917 if (tests[j].pool != D3DPOOL_SYSTEMMEM)
18919 IDirect3DTexture9_Release(texture);
18920 continue;
18923 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &dst_surface);
18924 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x.\n", hr);
18925 IDirect3DTexture9_GetSurfaceLevel(texture_sysmem, 0, &src_surface);
18926 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x.\n", hr);
18928 hr = IDirect3DDevice9_UpdateSurface(device, src_surface,
18929 &tests[j].src_rect, dst_surface, &tests[j].dst_point);
18930 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
18932 IDirect3DSurface9_Release(dst_surface);
18933 IDirect3DSurface9_Release(src_surface);
18935 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00003300, 0.0f, 0);
18936 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18937 hr = IDirect3DDevice9_BeginScene(device);
18938 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18939 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
18940 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18941 hr = IDirect3DDevice9_EndScene(device);
18942 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18944 for (y = 0; y < 4; y++)
18946 for (x = 0; x < tests[j].width; x++)
18948 if (tests[j].width == 4)
18949 expected_color = expected_colors2[y][x];
18950 else
18951 expected_color = expected_colors3[y];
18953 if (!formats[i].blue)
18954 expected_color |= 0x000000ff;
18956 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
18957 ok(color_match(color, expected_color, formats[i].slop)
18958 || broken(color_match(color, expected_color, formats[i].slop_broken)),
18959 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
18960 expected_color, color, formats[i].name, x, y);
18963 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18964 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18966 IDirect3DTexture9_Release(texture_sysmem);
18967 IDirect3DTexture9_Release(texture);
18971 IDirect3DPixelShader9_Release(shader);
18972 IDirect3DPixelShader9_Release(shader_alpha);
18974 done:
18975 refcount = IDirect3DDevice9_Release(device);
18976 ok(!refcount, "Device has %u references left.\n", refcount);
18977 IDirect3D9_Release(d3d);
18978 DestroyWindow(window);
18981 static void test_multisample_mismatch(void)
18983 IDirect3DDevice9 *device;
18984 IDirect3D9 *d3d;
18985 HWND window;
18986 HRESULT hr;
18987 D3DCOLOR color;
18988 ULONG refcount;
18989 IDirect3DSurface9 *rt, *rt_multi, *ds;
18990 static const struct
18992 struct vec3 position;
18993 DWORD color;
18995 quad[] =
18997 {{ -1.0f, -1.0f, 0.0f}, 0x000000ff},
18998 {{ -1.0f, 1.0f, 0.0f}, 0x000000ff},
18999 {{ 1.0f, -1.0f, 1.0f}, 0x000000ff},
19000 {{ 1.0f, 1.0f, 1.0f}, 0x000000ff},
19003 window = create_window();
19004 d3d = Direct3DCreate9(D3D_SDK_VERSION);
19005 ok(!!d3d, "Failed to create a D3D object.\n");
19006 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
19007 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
19009 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample mismatch test.\n");
19010 IDirect3D9_Release(d3d);
19011 return;
19013 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
19014 D3DFMT_D24X8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
19016 skip("Multisampling not supported for D3DFMT_D24X8, skipping multisample mismatch test.\n");
19017 IDirect3D9_Release(d3d);
19018 return;
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_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
19030 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt_multi, NULL);
19031 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
19033 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.1f, 0);
19034 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19036 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
19037 ok(SUCCEEDED(hr), "Failed to set depth stencil, hr %#x.\n", hr);
19038 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
19039 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
19040 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
19041 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19043 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
19044 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19045 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
19046 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19048 /* Clear with incompatible buffers. Partial and combined clears. */
19049 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
19050 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19051 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.3f, 0);
19052 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19053 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 0.5f, 0);
19054 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19056 /* The color buffer is reliably cleared on AMD and Nvidia GPUs. */
19057 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
19058 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19059 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
19060 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
19061 color = getPixelColor(device, 320, 240);
19062 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
19063 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19064 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19066 /* Check depth buffer values. AMD GPUs (r500 and evergreen tested) clear the depth buffer
19067 * like you'd expect in a correct framebuffer setup. Nvidia doesn't clear it, neither in
19068 * the Z only clear case nor in the combined clear case. */
19069 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
19070 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
19071 hr = IDirect3DDevice9_BeginScene(device);
19072 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19073 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19074 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19075 hr = IDirect3DDevice9_EndScene(device);
19076 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19077 color = getPixelColor(device, 62, 240);
19078 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
19079 color = getPixelColor(device, 64, 240);
19080 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x000000ff, 1)),
19081 "Got unexpected color 0x%08x.\n", color);
19082 color = getPixelColor(device, 318, 240);
19083 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x000000ff, 1)),
19084 "Got unexpected color 0x%08x.\n", color);
19085 color = getPixelColor(device, 322, 240);
19086 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
19087 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19088 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19090 /* Draw with incompatible buffers. AMD even performs Z testing, and the Z test
19091 * results appear to be correct for this simple draw. Nvidia doesn't draw unless
19092 * the depth test is disabled. Setting ZFUNC = ALWAYS doesn't make the geometry
19093 * show up either. Only test the ZENABLE = FALSE case for now. */
19094 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
19095 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19096 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
19097 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19098 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
19099 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19100 hr = IDirect3DDevice9_BeginScene(device);
19101 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19102 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19103 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19104 hr = IDirect3DDevice9_EndScene(device);
19105 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19107 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
19108 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19109 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
19110 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
19111 color = getPixelColor(device, 320, 240);
19112 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
19113 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19114 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19116 IDirect3DSurface9_Release(ds);
19118 /* Test the reverse situation: Multisampled depth buffer, single sampled color buffer.
19119 * Color clears work as expected, AMD also clears the depth buffer, Nvidia does not. */
19120 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24X8,
19121 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
19122 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#x.\n", hr);
19123 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
19124 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
19125 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
19126 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19127 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ffff00, 0.1f, 0);
19128 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19130 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
19131 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19132 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
19133 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19134 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.3f, 0);
19135 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19136 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 0.5f, 0);
19137 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19139 color = getPixelColor(device, 320, 240);
19140 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
19141 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19142 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19144 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
19145 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19146 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
19147 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19148 hr = IDirect3DDevice9_BeginScene(device);
19149 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19150 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19151 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19152 hr = IDirect3DDevice9_EndScene(device);
19153 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19155 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
19156 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19157 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
19158 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
19159 color = getPixelColor(device, 62, 240);
19160 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
19161 color = getPixelColor(device, 318, 240);
19162 ok(color_match(color, 0x00ffff00, 1) || broken(color_match(color, 0x000000ff, 1)),
19163 "Got unexpected color 0x%08x.\n", color);
19164 color = getPixelColor(device, 322, 240);
19165 ok(color_match(color, 0x00ffff00, 1), "Got unexpected color 0x%08x.\n", color);
19166 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19167 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19169 /* Draw with a single sampled color buffer and a multisampled depth buffer. Again
19170 * AMD seems to perform correct Z testing, Nvidia doesn't draw unless the Z test
19171 * is disabled. Again only test the ZENABLE = FALSE case. */
19172 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
19173 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19174 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
19175 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19176 hr = IDirect3DDevice9_BeginScene(device);
19177 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19178 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19179 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19180 hr = IDirect3DDevice9_EndScene(device);
19181 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19182 color = getPixelColor(device, 320, 240);
19183 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
19184 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19185 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19187 IDirect3DSurface9_Release(rt);
19188 IDirect3DSurface9_Release(ds);
19189 IDirect3DSurface9_Release(rt_multi);
19191 refcount = IDirect3DDevice9_Release(device);
19192 ok(!refcount, "Device has %u references left.\n", refcount);
19193 IDirect3D9_Release(d3d);
19194 DestroyWindow(window);
19197 static void test_texcoordindex(void)
19199 static const D3DMATRIX mat =
19201 1.0f, 0.0f, 0.0f, 0.0f,
19202 0.0f, 0.0f, 0.0f, 0.0f,
19203 0.0f, 0.0f, 0.0f, 0.0f,
19204 0.0f, 0.0f, 0.0f, 0.0f,
19205 }}};
19206 static const struct
19208 struct vec3 pos;
19209 struct vec2 texcoord1;
19210 struct vec2 texcoord2;
19211 struct vec2 texcoord3;
19213 quad[] =
19215 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 1.0f}},
19216 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 0.0f}},
19217 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}, {1.0f, 0.0f}, {0.0f, 1.0f}},
19218 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 0.0f}},
19220 IDirect3DDevice9 *device;
19221 IDirect3D9 *d3d9;
19222 HWND window;
19223 HRESULT hr;
19224 IDirect3DTexture9 *texture1, *texture2;
19225 D3DLOCKED_RECT locked_rect;
19226 ULONG refcount;
19227 D3DCOLOR color;
19228 DWORD *ptr;
19230 window = create_window();
19231 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
19232 ok(!!d3d9, "Failed to create a D3D object.\n");
19233 if (!(device = create_device(d3d9, window, window, TRUE)))
19235 skip("Failed to create a D3D device, skipping tests.\n");
19236 IDirect3D9_Release(d3d9);
19237 DestroyWindow(window);
19238 return;
19241 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture1, NULL);
19242 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
19243 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
19244 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
19246 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
19247 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
19248 ptr = locked_rect.pBits;
19249 ptr[0] = 0xff000000;
19250 ptr[1] = 0xff00ff00;
19251 ptr[2] = 0xff0000ff;
19252 ptr[3] = 0xff00ffff;
19253 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
19254 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
19256 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
19257 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
19258 ptr = locked_rect.pBits;
19259 ptr[0] = 0xff000000;
19260 ptr[1] = 0xff0000ff;
19261 ptr[2] = 0xffff0000;
19262 ptr[3] = 0xffff00ff;
19263 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
19264 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
19266 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture1);
19267 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
19268 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *)texture2);
19269 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
19270 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX3);
19271 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
19272 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
19273 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
19274 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
19275 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
19276 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
19277 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
19278 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
19279 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
19280 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
19281 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
19282 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
19283 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
19284 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
19285 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
19287 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXCOORDINDEX, 1);
19288 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
19289 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 0);
19290 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
19292 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
19293 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19295 hr = IDirect3DDevice9_BeginScene(device);
19296 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19297 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19298 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19299 hr = IDirect3DDevice9_EndScene(device);
19300 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19302 color = getPixelColor(device, 160, 120);
19303 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
19304 color = getPixelColor(device, 480, 120);
19305 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19306 color = getPixelColor(device, 160, 360);
19307 ok(color_match(color, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color);
19308 color = getPixelColor(device, 480, 360);
19309 ok(color_match(color, 0x00ffffff, 2), "Got unexpected color 0x%08x.\n", color);
19311 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
19312 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
19313 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE1, &mat);
19314 ok(SUCCEEDED(hr), "Failed to set transformation matrix, hr %#x.\n", hr);
19316 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
19317 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19319 hr = IDirect3DDevice9_BeginScene(device);
19320 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19321 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19322 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19323 hr = IDirect3DDevice9_EndScene(device);
19324 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19326 color = getPixelColor(device, 160, 120);
19327 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
19328 color = getPixelColor(device, 480, 120);
19329 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19330 color = getPixelColor(device, 160, 360);
19331 ok(color_match(color, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color);
19332 color = getPixelColor(device, 480, 360);
19333 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19335 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
19336 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
19337 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 2);
19338 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
19340 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
19341 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19343 hr = IDirect3DDevice9_BeginScene(device);
19344 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19345 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19346 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19347 hr = IDirect3DDevice9_EndScene(device);
19348 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19350 color = getPixelColor(device, 160, 120);
19351 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
19352 color = getPixelColor(device, 480, 120);
19353 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19354 color = getPixelColor(device, 160, 360);
19355 ok(color_match(color, 0x00ff00ff, 2), "Got unexpected color 0x%08x.\n", color);
19356 color = getPixelColor(device, 480, 360);
19357 ok(color_match(color, 0x00ffff00, 2), "Got unexpected color 0x%08x.\n", color);
19359 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19360 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19362 IDirect3DTexture9_Release(texture1);
19363 IDirect3DTexture9_Release(texture2);
19365 refcount = IDirect3DDevice9_Release(device);
19366 ok(!refcount, "Device has %u references left.\n", refcount);
19367 IDirect3D9_Release(d3d9);
19368 DestroyWindow(window);
19371 static void test_vertex_blending(void)
19373 IDirect3DVertexDeclaration9 *vertex_declaration;
19374 IDirect3DDevice9 *device;
19375 IDirect3D9 *d3d;
19376 D3DCAPS9 caps;
19377 D3DCOLOR color;
19378 ULONG refcount;
19379 HWND window;
19380 HRESULT hr;
19381 int i;
19383 static const D3DMATRIX view_mat =
19385 2.0f / 10.0f, 0.0f, 0.0f, 0.0f,
19386 0.0f, 2.0f / 10.0f, 0.0f, 0.0f,
19387 0.0f, 0.0f, 1.0f, 0.0f,
19388 0.0f, 0.0f, 0.0f, 1.0f
19389 }}},
19390 upper_left =
19392 1.0f, 0.0f, 0.0f, 0.0f,
19393 0.0f, 1.0f, 0.0f, 0.0f,
19394 0.0f, 0.0f, 1.0f, 0.0f,
19395 -4.0f, 4.0f, 0.0f, 1.0f
19396 }}},
19397 lower_left =
19399 1.0f, 0.0f, 0.0f, 0.0f,
19400 0.0f, 1.0f, 0.0f, 0.0f,
19401 0.0f, 0.0f, 1.0f, 0.0f,
19402 -4.0f, -4.0f, 0.0f, 1.0f
19403 }}},
19404 upper_right =
19406 1.0f, 0.0f, 0.0f, 0.0f,
19407 0.0f, 1.0f, 0.0f, 0.0f,
19408 0.0f, 0.0f, 1.0f, 0.0f,
19409 4.0f, 4.0f, 0.0f, 1.0f
19410 }}},
19411 lower_right =
19413 1.0f, 0.0f, 0.0f, 0.0f,
19414 0.0f, 1.0f, 0.0f, 0.0f,
19415 0.0f, 0.0f, 1.0f, 0.0f,
19416 4.0f, -4.0f, 0.0f, 1.0f
19417 }}};
19419 static const POINT quad_upper_right_points[] =
19421 {576, 48}, {-1, -1},
19423 quad_upper_right_empty_points[] =
19425 {64, 48}, {64, 432}, {576, 432}, {320, 240}, {-1, -1}
19427 quad_center_points[] =
19429 {320, 240}, {-1, -1}
19431 quad_center_empty_points[] =
19433 {64, 48}, {576, 48}, {64, 432}, {576, 432}, {-1, -1}
19435 quad_upper_center_points[] =
19437 {320, 48}, {-1, -1}
19439 quad_upper_center_empty_points[] =
19441 {320, 240}, {64, 48}, {576, 48}, {-1, -1}
19443 quad_fullscreen_points[] =
19445 {320, 48}, {320, 240}, {64, 48}, {576, 48}, {64, 432}, {576, 432}, {-1, -1}
19447 quad_fullscreen_empty_points[] =
19449 {-1, -1}
19452 static const struct
19454 DWORD fvf;
19455 D3DVERTEXELEMENT9 decl_elements[3];
19456 struct
19458 struct
19460 struct vec3 position;
19461 struct vec3 blendweights;
19463 vertex_data_float[4];
19464 struct
19466 struct vec3 position;
19467 D3DCOLOR blendweights;
19469 vertex_data_d3dcolor[4];
19470 } s;
19471 const POINT *quad_points;
19472 const POINT *empty_points;
19474 tests[] =
19476 /* upper right */
19478 D3DFVF_XYZB3,
19479 {{0}},
19480 {{{{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
19481 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
19482 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
19483 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}}}},
19484 quad_upper_right_points, quad_upper_right_empty_points
19486 /* center */
19488 D3DFVF_XYZB3,
19489 {{0}},
19490 {{{{-1.0f, -1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}},
19491 {{-1.0f, 1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}},
19492 {{ 1.0f, -1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}},
19493 {{ 1.0f, 1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}}}},
19494 quad_center_points, quad_center_empty_points
19496 /* upper center */
19498 D3DFVF_XYZB3,
19499 {{0}},
19500 {{{{-1.0f, -1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}},
19501 {{-1.0f, 1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}},
19502 {{ 1.0f, -1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}},
19503 {{ 1.0f, 1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}}}},
19504 quad_upper_center_points, quad_upper_center_empty_points
19506 /* full screen */
19508 D3DFVF_XYZB3,
19509 {{0}},
19510 {{{{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}},
19511 {{-1.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}},
19512 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}},
19513 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}}}},
19514 quad_fullscreen_points, quad_fullscreen_empty_points
19516 /* D3DCOLOR, full screen */
19520 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
19521 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
19522 D3DDECL_END()
19524 {{{{0}}},
19525 {{{-1.0f, -1.0f, 0.0f}, 0x0000ff00},
19526 {{-1.0f, 1.0f, 0.0f}, 0x00ff0000},
19527 {{ 1.0f, -1.0f, 0.0f}, 0x000000ff},
19528 {{ 1.0f, 1.0f, 0.0f}, 0x00000000}}},
19529 quad_fullscreen_points, quad_fullscreen_empty_points
19533 window = create_window();
19534 d3d = Direct3DCreate9(D3D_SDK_VERSION);
19535 ok(!!d3d, "Failed to create a D3D object.\n");
19536 if (!(device = create_device(d3d, window, window, TRUE)))
19538 skip("Failed to create a D3D device, skipping tests.\n");
19539 goto done;
19542 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
19543 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
19544 if (caps.MaxVertexBlendMatrices < 4)
19546 skip("Only %u vertex blend matrices supported, skipping tests.\n", caps.MaxVertexBlendMatrices);
19547 IDirect3DDevice9_Release(device);
19548 goto done;
19551 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
19552 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
19554 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &view_mat);
19555 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19557 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &upper_left);
19558 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19559 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(1), &lower_left);
19560 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19561 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(2), &lower_right);
19562 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19563 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(3), &upper_right);
19564 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19566 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_VERTEXBLEND, D3DVBF_3WEIGHTS);
19567 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed %08x\n", hr);
19569 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
19571 const POINT *point;
19573 if (tests[i].fvf)
19575 hr = IDirect3DDevice9_SetFVF(device, tests[i].fvf);
19576 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
19577 vertex_declaration = NULL;
19579 else
19581 hr = IDirect3DDevice9_CreateVertexDeclaration(device, tests[i].decl_elements, &vertex_declaration);
19582 ok(SUCCEEDED(hr), "Failed to create vertex declaration, hr %#x.\n", hr);
19583 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
19584 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
19587 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
19588 ok(SUCCEEDED(hr), "Failed to clear %08x\n", hr);
19590 hr = IDirect3DDevice9_BeginScene(device);
19591 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19593 if (tests[i].fvf)
19594 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
19595 tests[i].s.vertex_data_float, sizeof(*tests[i].s.vertex_data_float));
19596 else
19597 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
19598 tests[i].s.vertex_data_d3dcolor, sizeof(*tests[i].s.vertex_data_d3dcolor));
19599 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19601 hr = IDirect3DDevice9_EndScene(device);
19602 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19604 point = tests[i].quad_points;
19605 while (point->x != -1 && point->y != -1)
19607 color = getPixelColor(device, point->x, point->y);
19608 ok(color_match(color, 0x00ffffff, 1), "Expected quad at %dx%d.\n", point->x, point->y);
19609 ++point;
19612 point = tests[i].empty_points;
19613 while (point->x != -1 && point->y != -1)
19615 color = getPixelColor(device, point->x, point->y);
19616 ok(color_match(color, 0x00000000, 1), "Unexpected quad at %dx%d.\n", point->x, point->y);
19617 ++point;
19620 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19621 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19623 if (vertex_declaration)
19624 IDirect3DVertexDeclaration9_Release(vertex_declaration);
19627 refcount = IDirect3DDevice9_Release(device);
19628 ok(!refcount, "Device has %u references left.\n", refcount);
19630 done:
19631 IDirect3D9_Release(d3d);
19632 DestroyWindow(window);
19635 static void test_updatetexture(void)
19637 IDirect3DDevice9 *device;
19638 IDirect3D9 *d3d9;
19639 HWND window;
19640 HRESULT hr;
19641 IDirect3DBaseTexture9 *src, *dst;
19642 unsigned int t, i, f, l, x, y, z;
19643 D3DLOCKED_RECT locked_rect;
19644 D3DLOCKED_BOX locked_box;
19645 ULONG refcount;
19646 D3DCAPS9 caps;
19647 D3DCOLOR color;
19648 BOOL ati2n_supported, do_visual_test;
19649 static const struct
19651 struct vec3 pos;
19652 struct vec2 texcoord;
19654 quad[] =
19656 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}},
19657 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}},
19658 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}},
19659 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
19661 static const struct
19663 struct vec3 pos;
19664 struct vec3 texcoord;
19666 quad_cube_tex[] =
19668 {{-1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, 0.5f}},
19669 {{-1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, 0.5f}},
19670 {{ 1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, -0.5f}},
19671 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, -0.5f}},
19673 static const struct
19675 UINT src_width, src_height;
19676 UINT dst_width, dst_height;
19677 UINT src_levels, dst_levels;
19678 D3DFORMAT src_format, dst_format;
19679 BOOL broken;
19681 tests[] =
19683 {8, 8, 8, 8, 0, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 0 */
19684 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 1 */
19685 {8, 8, 8, 8, 2, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 2 */
19686 {8, 8, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 3 */
19687 {8, 8, 8, 8, 4, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 4 */
19688 {8, 8, 2, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 5 */
19689 /* The WARP renderer doesn't handle these cases correctly. */
19690 {8, 8, 8, 8, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 6 */
19691 {8, 8, 4, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 7 */
19692 /* Not clear what happens here on Windows, it doesn't make much sense
19693 * though (on Nvidia it seems to upload the 4x4 surface into the 7x7
19694 * one or something like that). */
19695 /* {8, 8, 7, 7, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
19696 {8, 8, 8, 8, 1, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 8 */
19697 {4, 4, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 9 */
19698 /* This one causes weird behavior on Windows (it probably writes out
19699 * of the texture memory). */
19700 /* {8, 8, 4, 4, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
19701 {8, 4, 4, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 10 */
19702 {8, 4, 2, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 11 */
19703 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8, FALSE}, /* 12 */
19704 {8, 8, 8, 8, 4, 4, D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 13 */
19705 /* The data is converted correctly on AMD, on Nvidia nothing happens
19706 * (it draws a black quad). */
19707 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_R5G6B5, TRUE}, /* 14 */
19708 /* Here the data is converted on AMD, just copied and "reinterpreted" as
19709 * a 32 bit float on Nvidia (specifically the tested value becomes a
19710 * very small float number which we get as 0 in the test). */
19711 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_R32F, TRUE}, /* 15 */
19712 /* This one doesn't seem to give the expected results on AMD. */
19713 /* {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_Q8W8V8U8, FALSE}, */
19714 {8, 8, 8, 8, 4, 4, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 16 */
19715 {8, 8, 8, 8, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 17 */
19716 {8, 8, 2, 2, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 18 */
19718 static const struct
19720 D3DRESOURCETYPE type;
19721 DWORD fvf;
19722 const void *quad;
19723 unsigned int vertex_size;
19724 DWORD cap;
19725 const char *name;
19727 texture_types[] =
19729 {D3DRTYPE_TEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
19730 quad, sizeof(*quad), D3DPTEXTURECAPS_MIPMAP, "2D mipmapped"},
19732 {D3DRTYPE_CUBETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0),
19733 quad_cube_tex, sizeof(*quad_cube_tex), D3DPTEXTURECAPS_CUBEMAP, "Cube"},
19735 {D3DRTYPE_VOLUMETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
19736 quad, sizeof(*quad), D3DPTEXTURECAPS_VOLUMEMAP, "Volume"}
19739 window = create_window();
19740 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
19741 ok(!!d3d9, "Failed to create a D3D object.\n");
19742 if (!(device = create_device(d3d9, window, window, TRUE)))
19744 skip("Failed to create a D3D device, skipping tests.\n");
19745 IDirect3D9_Release(d3d9);
19746 DestroyWindow(window);
19747 return;
19750 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
19751 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
19753 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
19754 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#x.\n", hr);
19755 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
19756 ok(SUCCEEDED(hr), "Failed to set texture clamping state, hr %#x.\n", hr);
19757 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
19758 ok(SUCCEEDED(hr), "Failed to set texture clamping state, hr %#x.\n", hr);
19759 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
19760 ok(SUCCEEDED(hr), "Failed to set texture clamping state, hr %#x.\n", hr);
19761 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
19762 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19763 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
19764 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#x.\n", hr);
19765 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
19766 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#x.\n", hr);
19768 for (t = 0; t < sizeof(texture_types) / sizeof(*texture_types); ++t)
19770 if (!(caps.TextureCaps & texture_types[t].cap))
19772 skip("%s textures not supported, skipping some tests.\n", texture_types[t].name);
19773 continue;
19776 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
19777 D3DFMT_X8R8G8B8, 0, texture_types[t].type, MAKEFOURCC('A','T','I','2'))))
19779 skip("%s ATI2N textures are not supported, skipping some tests.\n", texture_types[t].name);
19780 ati2n_supported = FALSE;
19782 else
19784 ati2n_supported = TRUE;
19787 hr = IDirect3DDevice9_SetFVF(device, texture_types[t].fvf);
19788 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
19790 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
19792 if (tests[i].src_format == MAKEFOURCC('A','T','I','2') && !ati2n_supported)
19793 continue;
19795 switch (texture_types[t].type)
19797 case D3DRTYPE_TEXTURE:
19798 hr = IDirect3DDevice9_CreateTexture(device,
19799 tests[i].src_width, tests[i].src_height,
19800 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
19801 (IDirect3DTexture9 **)&src, NULL);
19802 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19803 hr = IDirect3DDevice9_CreateTexture(device,
19804 tests[i].dst_width, tests[i].dst_height,
19805 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
19806 (IDirect3DTexture9 **)&dst, NULL);
19807 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19808 break;
19809 case D3DRTYPE_CUBETEXTURE:
19810 hr = IDirect3DDevice9_CreateCubeTexture(device,
19811 tests[i].src_width,
19812 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
19813 (IDirect3DCubeTexture9 **)&src, NULL);
19814 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19815 hr = IDirect3DDevice9_CreateCubeTexture(device,
19816 tests[i].dst_width,
19817 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
19818 (IDirect3DCubeTexture9 **)&dst, NULL);
19819 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19820 break;
19821 case D3DRTYPE_VOLUMETEXTURE:
19822 hr = IDirect3DDevice9_CreateVolumeTexture(device,
19823 tests[i].src_width, tests[i].src_height, tests[i].src_width,
19824 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
19825 (IDirect3DVolumeTexture9 **)&src, NULL);
19826 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19827 hr = IDirect3DDevice9_CreateVolumeTexture(device,
19828 tests[i].dst_width, tests[i].dst_height, tests[i].dst_width,
19829 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
19830 (IDirect3DVolumeTexture9 **)&dst, NULL);
19831 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19832 break;
19833 default:
19834 trace("Unexpected resource type.\n");
19837 /* Skip the visual part of the test for ATI2N (laziness) and cases that
19838 * give a different (and unlikely to be useful) result. */
19839 do_visual_test = (tests[i].src_format == D3DFMT_A8R8G8B8 || tests[i].src_format == D3DFMT_X8R8G8B8)
19840 && tests[i].src_levels != 0
19841 && tests[i].src_width >= tests[i].dst_width && tests[i].src_height >= tests[i].dst_height
19842 && !(tests[i].src_width > tests[i].src_height && tests[i].dst_width < tests[i].dst_height);
19844 if (do_visual_test)
19846 DWORD *ptr = NULL;
19847 unsigned int width, height, depth, row_pitch = 0, slice_pitch = 0;
19849 for (f = 0; f < (texture_types[t].type == D3DRTYPE_CUBETEXTURE ? 6 : 1); ++f)
19851 width = tests[i].src_width;
19852 height = texture_types[t].type != D3DRTYPE_CUBETEXTURE ? tests[i].src_height : tests[i].src_width;
19853 depth = texture_types[t].type == D3DRTYPE_VOLUMETEXTURE ? width : 1;
19855 for (l = 0; l < tests[i].src_levels; ++l)
19857 switch (texture_types[t].type)
19859 case D3DRTYPE_TEXTURE:
19860 hr = IDirect3DTexture9_LockRect((IDirect3DTexture9 *)src,
19861 l, &locked_rect, NULL, 0);
19862 ptr = locked_rect.pBits;
19863 row_pitch = locked_rect.Pitch / sizeof(*ptr);
19864 break;
19865 case D3DRTYPE_CUBETEXTURE:
19866 hr = IDirect3DCubeTexture9_LockRect((IDirect3DCubeTexture9 *)src,
19867 f, l, &locked_rect, NULL, 0);
19868 ptr = locked_rect.pBits;
19869 row_pitch = locked_rect.Pitch / sizeof(*ptr);
19870 break;
19871 case D3DRTYPE_VOLUMETEXTURE:
19872 hr = IDirect3DVolumeTexture9_LockBox((IDirect3DVolumeTexture9 *)src,
19873 l, &locked_box, NULL, 0);
19874 ptr = locked_box.pBits;
19875 row_pitch = locked_box.RowPitch / sizeof(*ptr);
19876 slice_pitch = locked_box.SlicePitch / sizeof(*ptr);
19877 break;
19878 default:
19879 trace("Unexpected resource type.\n");
19881 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
19883 for (z = 0; z < depth; ++z)
19885 for (y = 0; y < height; ++y)
19887 for (x = 0; x < width; ++x)
19889 ptr[z * slice_pitch + y * row_pitch + x] = 0xff000000
19890 | (DWORD)(x / (width - 1.0f) * 255.0f) << 16
19891 | (DWORD)(y / (height - 1.0f) * 255.0f) << 8;
19896 switch (texture_types[t].type)
19898 case D3DRTYPE_TEXTURE:
19899 hr = IDirect3DTexture9_UnlockRect((IDirect3DTexture9 *)src, l);
19900 break;
19901 case D3DRTYPE_CUBETEXTURE:
19902 hr = IDirect3DCubeTexture9_UnlockRect((IDirect3DCubeTexture9 *)src, f, l);
19903 break;
19904 case D3DRTYPE_VOLUMETEXTURE:
19905 hr = IDirect3DVolumeTexture9_UnlockBox((IDirect3DVolumeTexture9 *)src, l);
19906 break;
19907 default:
19908 trace("Unexpected resource type.\n");
19910 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
19912 width >>= 1;
19913 if (!width)
19914 width = 1;
19915 height >>= 1;
19916 if (!height)
19917 height = 1;
19918 depth >>= 1;
19919 if (!depth)
19920 depth = 1;
19925 hr = IDirect3DDevice9_UpdateTexture(device, src, dst);
19926 if (FAILED(hr))
19928 todo_wine ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u, %u.\n", hr, t, i);
19929 IDirect3DBaseTexture9_Release(src);
19930 IDirect3DBaseTexture9_Release(dst);
19931 continue;
19933 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u, %u.\n", hr, t, i);
19935 if (do_visual_test)
19937 hr = IDirect3DDevice9_SetTexture(device, 0, dst);
19938 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
19940 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 1.0f, 0);
19941 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19943 hr = IDirect3DDevice9_BeginScene(device);
19944 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19945 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
19946 texture_types[t].quad, texture_types[t].vertex_size);
19947 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19948 hr = IDirect3DDevice9_EndScene(device);
19949 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19951 color = getPixelColor(device, 320, 240);
19952 ok (color_match(color, 0x007f7f00, 3) || broken(tests[i].broken)
19953 || broken(color == 0x00adbeef), /* WARP device often just breaks down. */
19954 "Got unexpected color 0x%08x, case %u, %u.\n", color, t, i);
19957 IDirect3DBaseTexture9_Release(src);
19958 IDirect3DBaseTexture9_Release(dst);
19961 refcount = IDirect3DDevice9_Release(device);
19962 ok(!refcount, "Device has %u references left.\n", refcount);
19963 IDirect3D9_Release(d3d9);
19964 DestroyWindow(window);
19967 static void test_depthbias(void)
19969 IDirect3DDevice9 *device;
19970 IDirect3D9 *d3d;
19971 IDirect3DSurface9 *ds;
19972 D3DCAPS9 caps;
19973 D3DCOLOR color;
19974 ULONG refcount;
19975 HWND window;
19976 HRESULT hr;
19977 unsigned int i;
19978 static const D3DFORMAT formats[] =
19980 D3DFMT_D16, D3DFMT_D24X8, D3DFMT_D32, D3DFMT_D24S8, MAKEFOURCC('I','N','T','Z'),
19982 /* The scaling factor detection function detects the wrong factor for
19983 * float formats on Nvidia, therefore the following tests are disabled.
19984 * The wined3d function detects 2^23 like for fixed point formats but
19985 * the test needs 2^22 to pass.
19987 * AMD GPUs need a different scaling factor for float depth buffers
19988 * (2^24) than fixed point (2^23), but the wined3d detection function
19989 * works there, producing the right result in the test.
19991 * D3DFMT_D32F_LOCKABLE, D3DFMT_D24FS8,
19995 static const struct
19997 struct vec3 position;
19999 quad[] =
20001 {{-1.0f, -1.0f, 0.0f}},
20002 {{-1.0f, 1.0f, 0.0f}},
20003 {{ 1.0f, -1.0f, 1.0f}},
20004 {{ 1.0f, 1.0f, 1.0f}},
20006 union
20008 float f;
20009 DWORD d;
20010 } conv;
20012 window = create_window();
20013 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20014 ok(!!d3d, "Failed to create a D3D object.\n");
20015 if (!(device = create_device(d3d, window, window, TRUE)))
20017 skip("Failed to create a D3D device, skipping tests.\n");
20018 goto done;
20021 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
20022 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
20023 if (!(caps.RasterCaps & D3DPRASTERCAPS_DEPTHBIAS))
20025 IDirect3DDevice9_Release(device);
20026 skip("D3DPRASTERCAPS_DEPTHBIAS not supported.\n");
20027 goto done;
20030 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
20031 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
20032 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
20033 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
20034 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
20035 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
20036 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
20037 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
20038 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
20039 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
20041 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
20043 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20044 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, formats[i])))
20046 skip("Depth format %u not supported, skipping.\n", formats[i]);
20047 continue;
20050 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, formats[i],
20051 D3DMULTISAMPLE_NONE, 0, FALSE, &ds, NULL);
20052 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
20053 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
20054 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
20055 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 0.5f, 0);
20056 ok(SUCCEEDED(hr), "Failed to clear %08x\n", hr);
20058 hr = IDirect3DDevice9_BeginScene(device);
20059 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
20061 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x00ff0000);
20062 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20063 conv.f = -0.2f;
20064 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
20065 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20066 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20067 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20069 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
20070 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20071 conv.f = 0.0f;
20072 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
20073 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20074 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20075 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20077 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x000000ff);
20078 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20079 conv.f = 0.2f;
20080 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
20081 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20082 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20083 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20085 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x00ffffff);
20086 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20087 conv.f = 0.4f;
20088 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
20089 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20090 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20091 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20093 color = getPixelColor(device, 61, 240);
20094 ok(color_match(color, 0x00ffffff, 1), "Got unexpected color %08x at x=62, format %u.\n", color, formats[i]);
20095 color = getPixelColor(device, 65, 240);
20097 /* The broken results are for the WARP driver on the testbot. It seems to initialize
20098 * a scaling factor based on the first depth format that is used. Other formats with
20099 * a different depth size then render incorrectly. */
20100 ok(color_match(color, 0x000000ff, 1) || broken(color_match(color, 0x00ffffff, 1)),
20101 "Got unexpected color %08x at x=64, format %u.\n", color, formats[i]);
20102 color = getPixelColor(device, 190, 240);
20103 ok(color_match(color, 0x000000ff, 1) || broken(color_match(color, 0x00ffffff, 1)),
20104 "Got unexpected color %08x at x=190, format %u.\n", color, formats[i]);
20106 color = getPixelColor(device, 194, 240);
20107 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ffffff, 1)),
20108 "Got unexpected color %08x at x=194, format %u.\n", color, formats[i]);
20109 color = getPixelColor(device, 318, 240);
20110 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ffffff, 1)),
20111 "Got unexpected color %08x at x=318, format %u.\n", color, formats[i]);
20113 color = getPixelColor(device, 322, 240);
20114 ok(color_match(color, 0x00ff0000, 1) || broken(color_match(color, 0x00000000, 1)),
20115 "Got unexpected color %08x at x=322, format %u.\n", color, formats[i]);
20116 color = getPixelColor(device, 446, 240);
20117 ok(color_match(color, 0x00ff0000, 1) || broken(color_match(color, 0x00000000, 1)),
20118 "Got unexpected color %08x at x=446, format %u.\n", color, formats[i]);
20120 color = getPixelColor(device, 450, 240);
20121 ok(color_match(color, 0x00000000, 1), "Got unexpected color %08x at x=446, format %u.\n", color, formats[i]);
20123 hr = IDirect3DDevice9_EndScene(device);
20124 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
20126 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20127 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
20128 IDirect3DSurface9_Release(ds);
20131 refcount = IDirect3DDevice9_Release(device);
20132 ok(!refcount, "Device has %u references left.\n", refcount);
20134 done:
20135 IDirect3D9_Release(d3d);
20136 DestroyWindow(window);
20139 static void test_flip(void)
20141 IDirect3DDevice9 *device;
20142 IDirect3D9 *d3d;
20143 ULONG refcount;
20144 HWND window;
20145 HRESULT hr;
20146 IDirect3DSurface9 *back_buffers[3], *test_surface;
20147 unsigned int i;
20148 D3DCOLOR color;
20149 D3DPRESENT_PARAMETERS present_parameters = {0};
20151 window = create_window();
20152 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20153 ok(!!d3d, "Failed to create a D3D object.\n");
20155 present_parameters.BackBufferWidth = 640;
20156 present_parameters.BackBufferHeight = 480;
20157 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
20158 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
20159 present_parameters.hDeviceWindow = window;
20160 present_parameters.Windowed = TRUE;
20161 present_parameters.BackBufferCount = 3;
20162 present_parameters.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
20163 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20164 window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
20165 if (!device)
20167 skip("Failed to create a D3D device, skipping tests.\n");
20168 IDirect3D9_Release(d3d);
20169 DestroyWindow(window);
20170 return;
20173 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
20175 hr = IDirect3DDevice9_GetBackBuffer(device, 0, i, D3DBACKBUFFER_TYPE_MONO, &back_buffers[i]);
20176 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
20178 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &test_surface);
20179 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
20180 ok(test_surface == back_buffers[0], "Expected render target %p, got %p.\n", back_buffers[0], test_surface);
20181 IDirect3DSurface9_Release(test_surface);
20183 hr = IDirect3DDevice9_SetRenderTarget(device, 0, back_buffers[2]);
20184 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
20186 hr = IDirect3DDevice9_ColorFill(device, back_buffers[0], NULL, 0xffff0000);
20187 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x.\n", hr);
20188 hr = IDirect3DDevice9_ColorFill(device, back_buffers[1], NULL, 0xff00ff00);
20189 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x.\n", hr);
20190 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
20191 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
20193 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20194 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20196 /* Render target is unmodified. */
20197 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &test_surface);
20198 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
20199 ok(test_surface == back_buffers[2], "Expected render target %p, got %p.\n", back_buffers[2], test_surface);
20200 IDirect3DSurface9_Release(test_surface);
20202 /* Backbuffer surface pointers are unmodified */
20203 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
20205 hr = IDirect3DDevice9_GetBackBuffer(device, 0, i, D3DBACKBUFFER_TYPE_MONO, &test_surface);
20206 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
20207 ok(test_surface == back_buffers[i], "Expected back buffer %u = %p, got %p.\n",
20208 i, back_buffers[i], test_surface);
20209 IDirect3DSurface9_Release(test_surface);
20212 /* Contents were changed. */
20213 color = getPixelColorFromSurface(back_buffers[0], 1, 1);
20214 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
20215 color = getPixelColorFromSurface(back_buffers[1], 1, 1);
20216 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
20218 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0f, 0);
20219 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
20221 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20222 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20224 color = getPixelColorFromSurface(back_buffers[0], 1, 1);
20225 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
20226 color = getPixelColorFromSurface(back_buffers[1], 1, 1);
20227 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
20229 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20230 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20232 color = getPixelColorFromSurface(back_buffers[0], 1, 1);
20233 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
20235 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
20236 IDirect3DSurface9_Release(back_buffers[i]);
20238 refcount = IDirect3DDevice9_Release(device);
20239 ok(!refcount, "Device has %u references left.\n", refcount);
20241 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20242 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
20244 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample flip test.\n");
20245 goto done;
20248 present_parameters.BackBufferCount = 2;
20249 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
20250 present_parameters.Flags = 0;
20251 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20252 window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
20254 for (i = 0; i < present_parameters.BackBufferCount; ++i)
20256 hr = IDirect3DDevice9_GetBackBuffer(device, 0, i, D3DBACKBUFFER_TYPE_MONO, &back_buffers[i]);
20257 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
20260 hr = IDirect3DDevice9_SetRenderTarget(device, 0, back_buffers[1]);
20261 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
20262 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0f, 0);
20263 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
20265 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20266 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20268 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
20269 D3DMULTISAMPLE_NONE, 0, TRUE, &test_surface, NULL);
20270 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
20271 hr = IDirect3DDevice9_StretchRect(device, back_buffers[0], NULL, test_surface, NULL, D3DTEXF_POINT);
20272 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
20274 color = getPixelColorFromSurface(test_surface, 1, 1);
20275 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
20277 IDirect3DSurface9_Release(test_surface);
20278 for (i = 0; i < present_parameters.BackBufferCount; ++i)
20279 IDirect3DSurface9_Release(back_buffers[i]);
20281 refcount = IDirect3DDevice9_Release(device);
20282 ok(!refcount, "Device has %u references left.\n", refcount);
20284 done:
20285 IDirect3D9_Release(d3d);
20286 DestroyWindow(window);
20289 static void test_uninitialized_varyings(void)
20291 static const D3DMATRIX mat =
20293 1.0f, 0.0f, 0.0f, 0.0f,
20294 0.0f, 1.0f, 0.0f, 0.0f,
20295 0.0f, 0.0f, 1.0f, 0.0f,
20296 0.0f, 0.0f, 0.0f, 1.0f,
20297 }}};
20298 static const struct vec3 quad[] =
20300 {-1.0f, -1.0f, 0.1f},
20301 {-1.0f, 1.0f, 0.1f},
20302 { 1.0f, -1.0f, 0.1f},
20303 { 1.0f, 1.0f, 0.1f},
20305 static const DWORD vs1_code[] =
20307 0xfffe0101, /* vs_1_1 */
20308 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20309 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
20310 0x0000ffff
20312 static const DWORD vs1_partial_code[] =
20314 0xfffe0101, /* vs_1_1 */
20315 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20316 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
20317 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
20318 0x00000001, 0xd0010000, 0xa0e40000, /* mov oD0.x, c0 */
20319 0x00000001, 0xd0010001, 0xa0e40000, /* mov oD1.x, c0 */
20320 0x00000001, 0xe0010000, 0xa0e40000, /* mov oT0.x, c0 */
20321 0x0000ffff
20323 static const DWORD vs2_code[] =
20325 0xfffe0200, /* vs_2_0 */
20326 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20327 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
20328 0x0000ffff
20330 static const DWORD vs2_partial_code[] =
20332 0xfffe0200, /* vs_2_0 */
20333 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20334 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
20335 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
20336 0x02000001, 0xd0010000, 0xa0e40000, /* mov oD0.x, c0 */
20337 0x02000001, 0xd0010001, 0xa0e40000, /* mov oD1.x, c0 */
20338 0x02000001, 0xe0010000, 0xa0e40000, /* mov oT0.x, c0 */
20339 0x0000ffff
20341 static const DWORD vs3_code[] =
20343 0xfffe0300, /* vs_3_0 */
20344 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20345 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
20346 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
20347 0x0000ffff
20349 static const DWORD vs3_partial_code[] =
20351 0xfffe0300, /* vs_3_0 */
20352 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20353 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
20354 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
20355 0x0200001f, 0x8001000a, 0xe00f0002, /* dcl_color1 o2 */
20356 0x0200001f, 0x80000005, 0xe00f0003, /* dcl_texcoord0 o3 */
20357 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
20358 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
20359 0x02000001, 0xe0010001, 0xa0e40000, /* mov o1.x, c0 */
20360 0x02000001, 0xe0010002, 0xa0e40000, /* mov o2.x, c0 */
20361 0x02000001, 0xe0010003, 0xa0e40000, /* mov o3.x, c0 */
20362 0x0000ffff
20364 static const DWORD ps1_diffuse_code[] =
20366 0xffff0101, /* ps_1_1 */
20367 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
20368 0x0000ffff
20370 static const DWORD ps1_specular_code[] =
20372 0xffff0101, /* ps_1_1 */
20373 0x00000001, 0x800f0000, 0x90e40001, /* mov r0, v1 */
20374 0x0000ffff
20376 static const DWORD ps1_texcoord_code[] =
20378 0xffff0101, /* ps_1_1 */
20379 0x00000040, 0xb00f0000, /* texcoord t0 */
20380 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
20381 0x0000ffff
20383 static const DWORD ps2_diffuse_code[] =
20385 0xffff0200, /* ps_2_0 */
20386 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
20387 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
20388 0x0000ffff
20390 static const DWORD ps2_specular_code[] =
20392 0xffff0200, /* ps_2_0 */
20393 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
20394 0x02000001, 0x800f0800, 0x90e40001, /* mov oC0, v1 */
20395 0x0000ffff
20397 static const DWORD ps2_texcoord_code[] =
20399 0xffff0200, /* ps_2_0 */
20400 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
20401 0x02000001, 0x800f0800, 0xb0e40000, /* mov oC0, t0 */
20402 0x0000ffff
20404 static const DWORD ps3_diffuse_code[] =
20406 0xffff0300, /* ps_3_0 */
20407 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
20408 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
20409 0x0000ffff
20411 static const DWORD ps3_specular_code[] =
20413 0xffff0300, /* ps_3_0 */
20414 0x0200001f, 0x8001000a, 0x900f0001, /* dcl_color1 v1 */
20415 0x02000001, 0x800f0800, 0x90e40001, /* mov oC0, v1 */
20416 0x0000ffff
20418 static const DWORD ps3_texcoord_code[] =
20420 0xffff0300, /* ps_3_0 */
20421 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
20422 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
20423 0x0000ffff
20425 static const struct
20427 DWORD vs_version;
20428 const DWORD *vs;
20429 DWORD ps_version;
20430 const DWORD *ps;
20431 D3DCOLOR expected;
20432 BOOL allow_zero_alpha;
20433 BOOL allow_zero;
20434 BOOL broken_warp;
20436 /* On AMD specular color is generally initialized to 0x00000000 and texcoords to 0xff000000
20437 * while on Nvidia it's the opposite. Just allow both. */
20438 tests[] =
20440 {D3DVS_VERSION(1, 1), vs1_code, 0, NULL, 0xffffffff},
20441 { 0, NULL, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff000000, TRUE},
20442 { 0, NULL, D3DPS_VERSION(2, 0), ps2_texcoord_code, 0xff000000, TRUE},
20443 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_diffuse_code, 0xffffffff},
20444 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_specular_code, 0xff000000, TRUE, FALSE, TRUE},
20445 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff000000, TRUE},
20446 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_diffuse_code, 0xffffffff},
20447 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_specular_code, 0xff000000, TRUE, FALSE, TRUE},
20448 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_texcoord_code, 0xff000000, TRUE},
20449 {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_diffuse_code, 0xffffffff, FALSE, TRUE},
20450 {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_specular_code, 0x00000000, FALSE, FALSE, TRUE},
20451 {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_texcoord_code, 0x00000000, FALSE, FALSE, TRUE},
20452 {D3DVS_VERSION(1, 1), vs1_partial_code, 0, NULL, 0xff7fffff, FALSE, FALSE, TRUE},
20453 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_diffuse_code, 0xff7fffff, FALSE, FALSE, TRUE},
20454 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_specular_code, 0xff7f0000, TRUE},
20455 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff7f0000, TRUE},
20456 {D3DVS_VERSION(2, 0), vs2_partial_code, D3DPS_VERSION(2, 0), ps2_diffuse_code, 0xff7fffff, FALSE, FALSE, TRUE},
20457 {D3DVS_VERSION(2, 0), vs2_partial_code, D3DPS_VERSION(2, 0), ps2_specular_code, 0xff7f0000, TRUE},
20458 {D3DVS_VERSION(2, 0), vs2_partial_code, D3DPS_VERSION(2, 0), ps2_texcoord_code, 0xff7f0000, TRUE},
20459 /* Fails on Radeon HD 2600 with 0x008000ff aka nonsensical color. */
20460 /* {D3DVS_VERSION(3, 0), vs3_partial_code, D3DPS_VERSION(3, 0), ps3_diffuse_code, 0xff7fffff, TRUE}, */
20461 /* Randomly fails on Radeon HD 2600. */
20462 /* {D3DVS_VERSION(3, 0), vs3_partial_code, D3DPS_VERSION(3, 0), ps3_specular_code, 0x007f0000}, */
20463 {D3DVS_VERSION(3, 0), vs3_partial_code, D3DPS_VERSION(3, 0), ps3_texcoord_code, 0xff7f0000, TRUE},
20465 IDirect3DDevice9 *device;
20466 IDirect3D9 *d3d;
20467 HWND window;
20468 HRESULT hr;
20469 D3DADAPTER_IDENTIFIER9 identifier;
20470 IDirect3DSurface9 *backbuffer;
20471 struct surface_readback rb;
20472 IDirect3DVertexShader9 *vs;
20473 IDirect3DPixelShader9 *ps;
20474 unsigned int i;
20475 ULONG refcount;
20476 D3DCAPS9 caps;
20477 D3DCOLOR color;
20478 BOOL warp;
20480 window = create_window();
20481 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20482 ok(!!d3d, "Failed to create a D3D object.\n");
20483 if (!(device = create_device(d3d, window, window, TRUE)))
20485 skip("Failed to create a D3D device, skipping tests.\n");
20486 IDirect3D9_Release(d3d);
20487 DestroyWindow(window);
20488 return;
20491 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
20492 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
20493 warp = adapter_is_warp(&identifier);
20495 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
20496 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
20498 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
20499 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
20501 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
20502 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
20503 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
20504 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
20505 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
20506 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
20507 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
20508 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
20509 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
20510 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
20511 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
20512 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
20513 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
20514 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#x.\n", hr);
20515 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
20516 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
20518 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
20519 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
20521 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
20523 if (caps.VertexShaderVersion < tests[i].vs_version
20524 || caps.PixelShaderVersion < tests[i].ps_version)
20526 skip("Vertex / pixel shader version not supported, skipping test %u.\n", i);
20527 continue;
20529 if (tests[i].vs)
20531 hr = IDirect3DDevice9_CreateVertexShader(device, tests[i].vs, &vs);
20532 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
20534 else
20536 vs = NULL;
20538 if (tests[i].ps)
20540 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].ps, &ps);
20541 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
20543 else
20545 ps = NULL;
20548 hr = IDirect3DDevice9_SetVertexShader(device, vs);
20549 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
20550 hr = IDirect3DDevice9_SetPixelShader(device, ps);
20551 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
20553 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
20554 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
20556 hr = IDirect3DDevice9_BeginScene(device);
20557 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
20559 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
20560 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20562 hr = IDirect3DDevice9_EndScene(device);
20563 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
20565 get_rt_readback(backbuffer, &rb);
20566 color = get_readback_color(&rb, 320, 240);
20567 ok(color_match(color, tests[i].expected, 1)
20568 || (tests[i].allow_zero_alpha && color_match(color, tests[i].expected & 0x00ffffff, 1))
20569 || (tests[i].allow_zero && !color) || (broken(warp && tests[i].broken_warp)),
20570 "Got unexpected color 0x%08x, case %u.\n", color, i);
20571 release_surface_readback(&rb);
20573 if (vs)
20574 IDirect3DVertexShader9_Release(vs);
20575 if (ps)
20576 IDirect3DVertexShader9_Release(ps);
20579 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20580 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20582 IDirect3DSurface9_Release(backbuffer);
20583 refcount = IDirect3DDevice9_Release(device);
20584 ok(!refcount, "Device has %u references left.\n", refcount);
20585 IDirect3D9_Release(d3d);
20586 DestroyWindow(window);
20589 static void test_multisample_init(void)
20591 IDirect3DDevice9 *device;
20592 IDirect3D9 *d3d;
20593 IDirect3DSurface9 *back, *multi;
20594 ULONG refcount;
20595 HWND window;
20596 HRESULT hr;
20597 D3DCOLOR color;
20598 unsigned int x, y;
20599 struct surface_readback rb;
20600 BOOL all_zero = TRUE;
20602 window = create_window();
20603 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20604 ok(!!d3d, "Failed to create a D3D object.\n");
20606 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20607 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
20609 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample init test.\n");
20610 goto done;
20613 if (!(device = create_device(d3d, window, window, TRUE)))
20615 skip("Failed to create a D3D device, skipping tests.\n");
20616 goto done;
20619 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &back);
20620 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
20621 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
20622 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &multi, NULL);
20623 ok(SUCCEEDED(hr), "Failed to create multisampled render target, hr %#x.\n", hr);
20625 hr = IDirect3DDevice9_StretchRect(device, multi, NULL, back, NULL, D3DTEXF_POINT);
20626 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
20628 get_rt_readback(back, &rb);
20629 for (y = 0; y < 480; ++y)
20631 for (x = 0; x < 640; x++)
20633 color = get_readback_color(&rb, x, y);
20634 if (!color_match(color, 0x00000000, 0))
20636 all_zero = FALSE;
20637 break;
20640 if (!all_zero)
20641 break;
20643 release_surface_readback(&rb);
20644 ok(all_zero, "Got unexpected color 0x%08x, position %ux%u.\n", color, x, y);
20646 IDirect3DSurface9_Release(multi);
20647 IDirect3DSurface9_Release(back);
20649 refcount = IDirect3DDevice9_Release(device);
20650 ok(!refcount, "Device has %u references left.\n", refcount);
20652 done:
20653 IDirect3D9_Release(d3d);
20654 DestroyWindow(window);
20657 static void test_texture_blending(void)
20659 #define STATE_END() {0xffffffff, 0xffffffff}
20660 #define IS_STATE_END(s) (s.name == 0xffffffff && s.value == 0xffffffff)
20662 IDirect3DTexture9 *texture_bumpmap, *texture_red;
20663 IDirect3DSurface9 *backbuffer;
20664 struct surface_readback rb;
20665 D3DLOCKED_RECT locked_rect;
20666 IDirect3DDevice9 *device;
20667 unsigned int i, j, k;
20668 IDirect3D9 *d3d;
20669 D3DCOLOR color;
20670 ULONG refcount;
20671 D3DCAPS9 caps;
20672 HWND window;
20673 HRESULT hr;
20675 static const struct
20677 struct vec3 position;
20678 DWORD diffuse;
20680 quad[] =
20682 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
20683 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
20684 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
20685 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
20688 static const float bumpenvmat[4] = {1.0f, 1.0f, 0.0f, 0.0f};
20690 struct texture_stage_state
20692 D3DTEXTURESTAGESTATETYPE name;
20693 DWORD value;
20696 struct texture_stage
20698 enum
20700 TEXTURE_INVALID,
20701 TEXTURE_NONE,
20702 TEXTURE_BUMPMAP,
20703 TEXTURE_RED,
20705 texture;
20706 struct texture_stage_state state[20];
20709 static const struct texture_stage default_stage_state =
20711 TEXTURE_NONE,
20713 {D3DTSS_COLOROP, D3DTOP_DISABLE},
20714 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
20715 {D3DTSS_COLORARG2, D3DTA_CURRENT},
20716 {D3DTSS_ALPHAOP, D3DTOP_DISABLE},
20717 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
20718 {D3DTSS_ALPHAARG2, D3DTA_CURRENT},
20719 {D3DTSS_BUMPENVMAT00, 0},
20720 {D3DTSS_BUMPENVMAT01, 0},
20721 {D3DTSS_BUMPENVMAT10, 0},
20722 {D3DTSS_BUMPENVMAT11, 0},
20723 {D3DTSS_BUMPENVLSCALE, 0},
20724 {D3DTSS_BUMPENVLOFFSET, 0},
20725 {D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE},
20726 {D3DTSS_COLORARG0, D3DTA_CURRENT},
20727 {D3DTSS_ALPHAARG0, D3DTA_CURRENT},
20728 {D3DTSS_RESULTARG, D3DTA_CURRENT},
20729 {D3DTSS_CONSTANT, 0},
20730 STATE_END(),
20734 const struct test
20736 DWORD tex_op_caps;
20737 D3DCOLOR expected_color;
20738 struct texture_stage stage[8];
20740 tests[] =
20743 D3DTEXOPCAPS_DISABLE,
20744 0x80ffff02,
20747 TEXTURE_NONE,
20749 STATE_END(),
20755 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
20756 0x80ffff02,
20759 TEXTURE_NONE,
20761 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
20762 {D3DTSS_COLORARG1, D3DTA_CURRENT},
20763 STATE_END(),
20766 {TEXTURE_INVALID}
20770 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
20771 0x80ffff02,
20774 TEXTURE_NONE,
20776 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
20777 {D3DTSS_COLORARG1, D3DTA_CURRENT},
20778 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20779 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
20780 STATE_END(),
20786 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
20787 0x80ffff02,
20790 TEXTURE_NONE,
20792 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
20793 {D3DTSS_COLORARG1, D3DTA_DIFFUSE},
20794 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20795 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
20796 STATE_END(),
20802 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
20803 0x00000000,
20806 TEXTURE_NONE,
20808 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
20809 {D3DTSS_COLORARG1, D3DTA_TEMP},
20810 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20811 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
20812 STATE_END(),
20818 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_SUBTRACT,
20819 0x80f0f000,
20822 TEXTURE_NONE,
20824 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
20825 {D3DTSS_COLORARG1, D3DTA_CURRENT},
20826 STATE_END(),
20830 TEXTURE_NONE,
20832 {D3DTSS_COLOROP, D3DTOP_SUBTRACT},
20833 {D3DTSS_COLORARG1, D3DTA_CURRENT},
20834 {D3DTSS_COLORARG2, D3DTA_CONSTANT},
20835 {D3DTSS_CONSTANT, 0x0f0f0f0f},
20836 STATE_END(),
20839 {TEXTURE_INVALID}
20843 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_SUBTRACT,
20844 0x71f0f000,
20847 TEXTURE_NONE,
20849 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
20850 {D3DTSS_COLORARG1, D3DTA_CURRENT},
20851 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20852 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
20853 STATE_END(),
20857 TEXTURE_NONE,
20859 {D3DTSS_COLOROP, D3DTOP_SUBTRACT},
20860 {D3DTSS_COLORARG1, D3DTA_CURRENT},
20861 {D3DTSS_COLORARG2, D3DTA_CONSTANT},
20862 {D3DTSS_ALPHAOP, D3DTOP_SUBTRACT},
20863 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
20864 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
20865 {D3DTSS_CONSTANT, 0x0f0f0f0f},
20866 STATE_END(),
20869 {TEXTURE_INVALID}
20874 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
20875 0x80ff0000,
20878 TEXTURE_BUMPMAP,
20880 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
20881 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
20882 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
20883 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
20884 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
20885 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20886 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
20887 STATE_END(),
20892 TEXTURE_RED,
20894 {D3DTSS_COLOROP, D3DTOP_MODULATE},
20895 STATE_END(),
20898 {TEXTURE_INVALID}
20902 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
20903 0x80ff0000,
20906 TEXTURE_BUMPMAP,
20908 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
20909 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
20910 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
20911 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
20912 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
20913 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20914 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
20915 STATE_END(),
20919 TEXTURE_RED,
20921 {D3DTSS_COLOROP, D3DTOP_MODULATE},
20922 STATE_END(),
20925 {TEXTURE_INVALID}
20929 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
20930 0x80ff0000,
20933 TEXTURE_BUMPMAP,
20935 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
20936 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
20937 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
20938 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
20939 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
20940 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20941 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
20942 STATE_END(),
20946 TEXTURE_RED,
20948 {D3DTSS_COLOROP, D3DTOP_MODULATE},
20949 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20950 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
20951 STATE_END(),
20954 {TEXTURE_INVALID}
20958 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
20959 0x00ff0000,
20962 TEXTURE_BUMPMAP,
20964 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
20965 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
20966 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
20967 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
20968 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
20969 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20970 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
20971 STATE_END(),
20975 TEXTURE_RED,
20977 {D3DTSS_COLOROP, D3DTOP_MODULATE},
20978 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
20979 {D3DTSS_COLORARG2, D3DTA_CURRENT},
20980 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20981 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
20982 STATE_END(),
20985 {TEXTURE_INVALID}
20989 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
20990 0x80ff0000,
20993 TEXTURE_BUMPMAP,
20995 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
20996 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
20997 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
20998 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
20999 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21000 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21001 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21002 STATE_END(),
21006 TEXTURE_RED,
21008 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21009 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21010 {D3DTSS_COLORARG2, D3DTA_CURRENT},
21011 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21012 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21013 STATE_END(),
21016 {TEXTURE_INVALID}
21021 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
21022 | D3DTEXOPCAPS_ADD,
21023 0x80ff0000,
21026 TEXTURE_BUMPMAP,
21028 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21029 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21030 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21031 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21032 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21033 {D3DTSS_ALPHAOP, D3DTOP_ADD},
21034 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
21035 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
21036 {D3DTSS_CONSTANT, 0x0fffffff},
21037 STATE_END(),
21041 TEXTURE_RED,
21043 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21044 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21045 {D3DTSS_COLORARG2, D3DTA_CURRENT},
21046 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21047 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21048 STATE_END(),
21051 {TEXTURE_INVALID}
21055 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
21056 | D3DTEXOPCAPS_MODULATE2X,
21057 0x80ff0000,
21060 TEXTURE_BUMPMAP,
21062 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21063 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21064 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21065 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21066 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21067 {D3DTSS_ALPHAOP, D3DTOP_MODULATE2X},
21068 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
21069 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
21070 {D3DTSS_CONSTANT, 0x01ffffff},
21071 STATE_END(),
21075 TEXTURE_RED,
21077 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21078 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21079 {D3DTSS_COLORARG2, D3DTA_CURRENT},
21080 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21081 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21082 STATE_END(),
21085 {TEXTURE_INVALID}
21089 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
21090 | D3DTEXOPCAPS_MODULATE2X,
21091 0x80ffff00,
21094 TEXTURE_BUMPMAP,
21096 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21097 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21098 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21099 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21100 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21101 {D3DTSS_ALPHAOP, D3DTOP_MODULATE2X},
21102 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21103 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
21104 {D3DTSS_CONSTANT, 0x01ffffff},
21105 STATE_END(),
21109 TEXTURE_RED,
21111 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21112 {D3DTSS_COLORARG1, D3DTA_CURRENT},
21113 {D3DTSS_COLORARG2, D3DTA_CURRENT},
21114 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21115 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21116 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
21117 {D3DTSS_ALPHAARG0, D3DTA_CONSTANT},
21118 STATE_END(),
21121 {TEXTURE_INVALID}
21125 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
21126 0x01234567,
21129 TEXTURE_NONE,
21131 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21132 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
21133 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21134 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
21135 {D3DTSS_RESULTARG, D3DTA_TEMP},
21136 {D3DTSS_CONSTANT, 0x01234567},
21137 STATE_END(),
21141 TEXTURE_BUMPMAP,
21143 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21144 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21145 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21146 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21147 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21148 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21149 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21150 {D3DTSS_RESULTARG, D3DTA_TEMP},
21151 STATE_END(),
21155 TEXTURE_RED,
21157 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21158 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21159 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21160 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
21161 STATE_END(),
21165 TEXTURE_NONE,
21167 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21168 {D3DTSS_COLORARG1, D3DTA_TEMP},
21169 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21170 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21171 STATE_END(),
21174 {TEXTURE_INVALID}
21178 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
21179 0x00234567,
21182 TEXTURE_NONE,
21184 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21185 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
21186 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21187 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
21188 {D3DTSS_RESULTARG, D3DTA_TEMP},
21189 {D3DTSS_CONSTANT, 0x01234567},
21190 STATE_END(),
21194 TEXTURE_BUMPMAP,
21196 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21197 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21198 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21199 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21200 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21201 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21202 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21203 STATE_END(),
21207 TEXTURE_RED,
21209 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21210 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21211 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21212 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
21213 STATE_END(),
21217 TEXTURE_NONE,
21219 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21220 {D3DTSS_COLORARG1, D3DTA_TEMP},
21221 STATE_END(),
21224 {TEXTURE_INVALID}
21228 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
21229 0x01234567,
21232 TEXTURE_NONE,
21234 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21235 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
21236 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21237 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
21238 {D3DTSS_RESULTARG, D3DTA_TEMP},
21239 {D3DTSS_CONSTANT, 0x01234567},
21240 STATE_END(),
21244 TEXTURE_BUMPMAP,
21246 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21247 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21248 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21249 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21250 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21251 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21252 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21253 {D3DTSS_RESULTARG, D3DTA_TEMP},
21254 STATE_END(),
21258 TEXTURE_RED,
21260 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21261 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21262 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21263 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
21264 STATE_END(),
21268 TEXTURE_NONE,
21270 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21271 {D3DTSS_COLORARG1, D3DTA_TEMP},
21272 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21273 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21274 STATE_END(),
21277 {TEXTURE_INVALID}
21281 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
21282 0x01234567,
21285 TEXTURE_NONE,
21287 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21288 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
21289 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21290 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
21291 {D3DTSS_RESULTARG, D3DTA_CURRENT},
21292 {D3DTSS_CONSTANT, 0x01234567},
21293 STATE_END(),
21297 TEXTURE_BUMPMAP,
21299 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21300 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21301 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21302 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21303 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21304 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21305 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21306 {D3DTSS_RESULTARG, D3DTA_TEMP},
21307 STATE_END(),
21311 TEXTURE_RED,
21313 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21314 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21315 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21316 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
21317 {D3DTSS_RESULTARG, D3DTA_TEMP},
21318 STATE_END(),
21322 TEXTURE_NONE,
21324 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21325 {D3DTSS_COLORARG1, D3DTA_CURRENT},
21326 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21327 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21328 {D3DTSS_RESULTARG, D3DTA_CURRENT},
21329 STATE_END(),
21332 {TEXTURE_INVALID}
21337 window = create_window();
21338 d3d = Direct3DCreate9(D3D_SDK_VERSION);
21339 ok(!!d3d, "Failed to create a D3D object.\n");
21340 if (!(device = create_device(d3d, window, window, TRUE)))
21342 skip("Failed to create a D3D device.\n");
21343 goto done;
21346 memset(&caps, 0, sizeof(caps));
21347 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
21348 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr %#x.\n", hr);
21350 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
21352 skip("D3DPMISCCAPS_TSSARGTEMP not supported.\n");
21353 IDirect3DDevice9_Release(device);
21354 goto done;
21357 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_PERSTAGECONSTANT))
21359 skip("D3DPMISCCAPS_PERSTAGECONSTANT not supported.\n");
21360 IDirect3DDevice9_Release(device);
21361 goto done;
21364 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
21365 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_V8U8)))
21367 skip("D3DFMT_V8U8 not supported for legacy bump mapping.\n");
21368 IDirect3DDevice9_Release(device);
21369 goto done;
21372 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
21373 ok(hr == D3D_OK, "Can't get back buffer, hr %#x.\n", hr);
21375 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture_bumpmap, NULL);
21376 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr %#x.\n", hr);
21377 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture_red, NULL);
21378 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr %#x.\n", hr);
21380 memset(&locked_rect, 0, sizeof(locked_rect));
21381 hr = IDirect3DTexture9_LockRect(texture_bumpmap, 0, &locked_rect, NULL, 0);
21382 ok(SUCCEEDED(hr), "LockRect failed, hr %#x.\n", hr);
21383 *((WORD *)locked_rect.pBits) = 0xff00;
21384 hr = IDirect3DTexture9_UnlockRect(texture_bumpmap, 0);
21385 ok(SUCCEEDED(hr), "UnlockRect failed, hr %#x.\n", hr);
21387 memset(&locked_rect, 0, sizeof(locked_rect));
21388 hr = IDirect3DTexture9_LockRect(texture_red, 0, &locked_rect, NULL, 0);
21389 ok(SUCCEEDED(hr), "LockRect failed, hr %#x.\n", hr);
21390 *((DWORD *)locked_rect.pBits) = 0x00ff0000;
21391 hr = IDirect3DTexture9_UnlockRect(texture_red, 0);
21392 ok(SUCCEEDED(hr), "UnlockRect failed, hr %#x.\n", hr);
21394 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
21395 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
21396 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
21397 ok(hr == D3D_OK, "Failed to disable lighting, hr %#x.\n", hr);
21399 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
21401 const struct test *current_test = &tests[i];
21403 if ((caps.TextureOpCaps & current_test->tex_op_caps) != current_test->tex_op_caps)
21405 skip("Texture operations %#x not supported.\n", current_test->tex_op_caps);
21406 continue;
21409 for (j = 0; j < caps.MaxTextureBlendStages; ++j)
21411 IDirect3DTexture9 *current_texture = NULL;
21413 for (k = 0; !IS_STATE_END(default_stage_state.state[k]); ++k)
21415 hr = IDirect3DDevice9_SetTextureStageState(device, j,
21416 default_stage_state.state[k].name, default_stage_state.state[k].value);
21417 ok(SUCCEEDED(hr), "Test %u: SetTextureStageState failed, hr %#x.\n", i, hr);
21420 if (current_test->stage[j].texture != TEXTURE_INVALID)
21422 const struct texture_stage_state *current_state = current_test->stage[j].state;
21424 switch (current_test->stage[j].texture)
21426 case TEXTURE_RED:
21427 current_texture = texture_red;
21428 break;
21429 case TEXTURE_BUMPMAP:
21430 current_texture = texture_bumpmap;
21431 break;
21432 default:
21433 current_texture = NULL;
21434 break;
21437 for (k = 0; !IS_STATE_END(current_state[k]); ++k)
21439 hr = IDirect3DDevice9_SetTextureStageState(device, j,
21440 current_state[k].name, current_state[k].value);
21441 ok(SUCCEEDED(hr), "Test %u: SetTextureStageState failed, hr %#x.\n", i, hr);
21445 hr = IDirect3DDevice9_SetTexture(device, j, (IDirect3DBaseTexture9 *)current_texture);
21446 ok(SUCCEEDED(hr), "Test %u: SetTexture failed, hr %#x.\n", i, hr);
21449 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
21450 ok(hr == D3D_OK, "Test %u: IDirect3DDevice9_Clear failed, hr %#x.\n", i, hr);
21452 hr = IDirect3DDevice9_BeginScene(device);
21453 ok(SUCCEEDED(hr), "Test %u: BeginScene failed, hr %#x.\n", i, hr);
21454 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
21455 ok(SUCCEEDED(hr), "Test %u: DrawPrimitiveUP failed, hr %#x.\n", i, hr);
21456 hr = IDirect3DDevice9_EndScene(device);
21457 ok(SUCCEEDED(hr), "Test %u: EndScene failed, hr %#x.\n", i, hr);
21459 get_rt_readback(backbuffer, &rb);
21460 color = get_readback_color(&rb, 320, 240);
21461 ok(color_match(color, current_test->expected_color, 1),
21462 "Test %u: Got color 0x%08x, expected 0x%08x.\n", i, color, current_test->expected_color);
21463 release_surface_readback(&rb);
21464 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21465 ok(SUCCEEDED(hr), "Test %u: Present failed, hr %#x.\n", i, hr);
21468 IDirect3DTexture9_Release(texture_bumpmap);
21469 IDirect3DTexture9_Release(texture_red);
21470 IDirect3DSurface9_Release(backbuffer);
21471 refcount = IDirect3DDevice9_Release(device);
21472 ok(!refcount, "Device has %u references left.\n", refcount);
21473 done:
21474 IDirect3D9_Release(d3d);
21475 DestroyWindow(window);
21478 static void test_color_clamping(void)
21480 static const D3DMATRIX mat =
21482 1.0f, 0.0f, 0.0f, 0.0f,
21483 0.0f, 1.0f, 0.0f, 0.0f,
21484 0.0f, 0.0f, 1.0f, 0.0f,
21485 0.0f, 0.0f, 0.0f, 1.0f,
21486 }}};
21487 static const struct vec3 quad[] =
21489 {-1.0f, -1.0f, 0.1f},
21490 {-1.0f, 1.0f, 0.1f},
21491 { 1.0f, -1.0f, 0.1f},
21492 { 1.0f, 1.0f, 0.1f},
21494 static const DWORD vs1_code[] =
21496 0xfffe0101, /* vs_1_1 */
21497 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
21498 0x00000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
21499 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
21500 0x00000002, 0xd00f0000, 0xa0e40000, 0xa0e40000, /* add oD0, c0, c0 */
21501 0x00000002, 0xd00f0001, 0xa0e40000, 0xa0e40000, /* add oD1, c0, c0 */
21502 0x0000ffff
21504 static const DWORD vs2_code[] =
21506 0xfffe0200, /* vs_2_0 */
21507 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
21508 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
21509 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
21510 0x03000002, 0xd00f0000, 0xa0e40000, 0xa0e40000, /* add oD0, c0, c0 */
21511 0x03000002, 0xd00f0001, 0xa0e40000, 0xa0e40000, /* add oD1, c0, c0 */
21512 0x0000ffff
21514 static const DWORD vs3_code[] =
21516 0xfffe0300, /* vs_3_0 */
21517 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
21518 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
21519 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
21520 0x0200001f, 0x8001000a, 0xe00f0002, /* dcl_color1 o2 */
21521 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
21522 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
21523 0x03000002, 0xe00f0001, 0xa0e40000, 0xa0e40000, /* add o1, c0, c0 */
21524 0x03000002, 0xe00f0002, 0xa0e40000, 0xa0e40000, /* add o2, c0, c0 */
21525 0x0000ffff
21527 static const DWORD ps1_code[] =
21529 0xffff0101, /* ps_1_1 */
21530 0x00000051, 0xa00f0000, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000, /* def c0, 0.25, 0.25, 0.25, 0.25 */
21531 0x00000002, 0x800f0000, 0x90e40000, 0x90e40001, /* add r0, v0, v1 */
21532 0x00000005, 0x800f0000, 0x80e40000, 0xa0e40000, /* mul r0, r0, c0 */
21533 0x0000ffff
21535 static const DWORD ps2_code[] =
21537 0xffff0200, /* ps_2_0 */
21538 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
21539 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
21540 0x05000051, 0xa00f0000, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000, /* def c0, 0.25, 0.25, 0.25, 0.25 */
21541 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
21542 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
21543 0x03000005, 0x800f0000, 0x80e40000, 0xa0e40000, /* mul r0, r0, c0 */
21544 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
21545 0x0000ffff
21547 static const DWORD ps3_code[] =
21549 0xffff0300, /* ps_3_0 */
21550 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
21551 0x0200001f, 0x8001000a, 0x900f0001, /* dcl_color1 v1 */
21552 0x05000051, 0xa00f0000, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000, /* def c0, 0.25, 0.25, 0.25, 0.25 */
21553 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
21554 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
21555 0x03000005, 0x800f0800, 0x80e40000, 0xa0e40000, /* mul oC0, r0, c0 */
21556 0x0000ffff
21558 static const struct
21560 DWORD vs_version;
21561 const DWORD *vs;
21562 DWORD ps_version;
21563 const DWORD *ps;
21564 D3DCOLOR expected, broken;
21566 tests[] =
21568 {0, NULL, 0, NULL, 0x00404040},
21569 {0, NULL, D3DPS_VERSION(1, 1), ps1_code, 0x00404040, 0x00808080},
21570 {D3DVS_VERSION(1, 1), vs1_code, 0, NULL, 0x00404040},
21571 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_code, 0x007f7f7f},
21572 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_code, 0x007f7f7f},
21573 {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_code, 0x00ffffff},
21575 IDirect3DVertexShader9 *vs;
21576 IDirect3DPixelShader9 *ps;
21577 IDirect3DDevice9 *device;
21578 IDirect3D9 *d3d9;
21579 unsigned int i;
21580 ULONG refcount;
21581 D3DCOLOR color;
21582 D3DCAPS9 caps;
21583 HWND window;
21584 HRESULT hr;
21586 window = create_window();
21587 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
21588 ok(!!d3d9, "Failed to create a D3D object.\n");
21589 if (!(device = create_device(d3d9, window, window, TRUE)))
21591 skip("Failed to create a D3D device, skipping tests.\n");
21592 IDirect3D9_Release(d3d9);
21593 DestroyWindow(window);
21594 return;
21597 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
21598 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
21600 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
21601 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
21602 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
21603 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
21604 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
21605 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
21606 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
21607 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
21608 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
21609 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
21610 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
21611 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
21612 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
21613 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#x.\n", hr);
21614 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
21615 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
21616 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
21617 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
21619 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xff404040);
21620 ok(SUCCEEDED(hr), "Failed to set texture factor, hr %#x.\n", hr);
21621 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
21622 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
21623 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
21624 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
21625 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_SPECULAR);
21626 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
21627 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_MODULATE);
21628 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
21629 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
21630 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
21631 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
21632 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
21634 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
21635 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
21637 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
21639 if (caps.VertexShaderVersion < tests[i].vs_version
21640 || caps.PixelShaderVersion < tests[i].ps_version)
21642 skip("Vertex / pixel shader version not supported, skipping test %u.\n", i);
21643 continue;
21645 if (tests[i].vs)
21647 hr = IDirect3DDevice9_CreateVertexShader(device, tests[i].vs, &vs);
21648 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
21650 else
21652 vs = NULL;
21654 if (tests[i].ps)
21656 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].ps, &ps);
21657 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
21659 else
21661 ps = NULL;
21664 hr = IDirect3DDevice9_SetVertexShader(device, vs);
21665 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
21666 hr = IDirect3DDevice9_SetPixelShader(device, ps);
21667 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
21669 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
21670 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21672 hr = IDirect3DDevice9_BeginScene(device);
21673 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21675 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
21676 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
21678 hr = IDirect3DDevice9_EndScene(device);
21679 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
21681 color = getPixelColor(device, 320, 240);
21682 ok(color_match(color, tests[i].expected, 1) || broken(color_match(color, tests[i].broken, 1)),
21683 "Got unexpected color 0x%08x, case %u.\n", color, i);
21685 if (vs)
21686 IDirect3DVertexShader9_Release(vs);
21687 if (ps)
21688 IDirect3DVertexShader9_Release(ps);
21691 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21692 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
21694 refcount = IDirect3DDevice9_Release(device);
21695 ok(!refcount, "Device has %u references left.\n", refcount);
21696 IDirect3D9_Release(d3d9);
21697 DestroyWindow(window);
21700 static void test_line_antialiasing_blending(void)
21702 IDirect3DDevice9 *device;
21703 IDirect3D9 *d3d9;
21704 ULONG refcount;
21705 D3DCOLOR color;
21706 D3DCAPS9 caps;
21707 HWND window;
21708 HRESULT hr;
21710 static const struct
21712 struct vec3 position;
21713 DWORD diffuse;
21715 green_quad[] =
21717 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
21718 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
21719 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
21720 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
21722 static const struct
21724 struct vec3 position;
21725 DWORD diffuse;
21727 red_quad[] =
21729 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
21730 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
21731 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
21732 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
21735 window = create_window();
21736 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
21737 ok(!!d3d9, "Failed to create a D3D object.\n");
21738 if (!(device = create_device(d3d9, window, window, TRUE)))
21740 skip("Failed to create a D3D device.\n");
21741 IDirect3D9_Release(d3d9);
21742 DestroyWindow(window);
21743 return;
21746 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
21747 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
21748 trace("Line antialiasing support: %#x.\n", caps.LineCaps & D3DLINECAPS_ANTIALIAS);
21750 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
21751 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
21752 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
21753 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
21754 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
21755 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
21757 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
21758 ok(SUCCEEDED(hr), "Failed to enable blending, hr %#x.\n", hr);
21759 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_BLENDOP, D3DBLENDOP_ADD);
21760 ok(SUCCEEDED(hr), "Failed to set blend op, hr %#x.\n", hr);
21761 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
21762 ok(SUCCEEDED(hr), "Failed to set src blend, hr %#x.\n", hr);
21763 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_DESTALPHA);
21764 ok(SUCCEEDED(hr), "Failed to set dest blend, hr %#x.\n", hr);
21766 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
21767 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
21768 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
21769 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
21770 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
21771 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#x.\n", hr);
21772 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
21773 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#x.\n", hr);
21775 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
21776 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
21778 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
21779 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21780 hr = IDirect3DDevice9_BeginScene(device);
21781 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21782 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
21783 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
21784 hr = IDirect3DDevice9_EndScene(device);
21785 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
21786 color = getPixelColor(device, 320, 240);
21787 ok(color_match(color, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color);
21789 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
21790 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21791 hr = IDirect3DDevice9_BeginScene(device);
21792 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21793 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
21794 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
21795 hr = IDirect3DDevice9_EndScene(device);
21796 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
21797 color = getPixelColor(device, 320, 240);
21798 ok(color_match(color, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color);
21800 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
21801 ok(SUCCEEDED(hr), "Failed to disable blending, hr %#x.\n", hr);
21803 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
21804 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21805 hr = IDirect3DDevice9_BeginScene(device);
21806 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21807 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
21808 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
21809 hr = IDirect3DDevice9_EndScene(device);
21810 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
21811 color = getPixelColor(device, 320, 240);
21812 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
21814 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
21815 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21816 hr = IDirect3DDevice9_BeginScene(device);
21817 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21818 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
21819 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
21820 hr = IDirect3DDevice9_EndScene(device);
21821 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
21822 color = getPixelColor(device, 320, 240);
21823 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
21825 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ANTIALIASEDLINEENABLE, TRUE);
21826 ok(SUCCEEDED(hr), "Failed to enable line antialiasing, hr %#x.\n", hr);
21828 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
21829 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21830 hr = IDirect3DDevice9_BeginScene(device);
21831 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21832 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
21833 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
21834 hr = IDirect3DDevice9_EndScene(device);
21835 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
21836 color = getPixelColor(device, 320, 240);
21837 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
21839 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
21840 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21841 hr = IDirect3DDevice9_BeginScene(device);
21842 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21843 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
21844 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
21845 hr = IDirect3DDevice9_EndScene(device);
21846 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
21847 color = getPixelColor(device, 320, 240);
21848 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
21850 refcount = IDirect3DDevice9_Release(device);
21851 ok(!refcount, "Device has %u references left.\n", refcount);
21852 IDirect3D9_Release(d3d9);
21853 DestroyWindow(window);
21856 static void test_dsy(void)
21858 static const DWORD vs_code[] =
21860 0xfffe0300, /* vs_3_0 */
21861 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
21862 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
21863 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
21864 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
21865 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
21866 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
21867 0x0000ffff
21869 static const DWORD ps_code[] =
21871 0xffff0300, /* ps_3_0 */
21872 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
21873 0x05000051, 0xa00f0000, 0x43700000, 0x3f000000, 0x00000000, 0x00000000, /* def c0, 240.0, 0.5, 0.0, 0.0 */
21874 0x0200005c, 0x800f0000, 0x90e40000, /* dsy r0, v0 */
21875 0x03000005, 0x800f0000, 0x80e40000, 0xa0000000, /* mul r0, r0, c0.x */
21876 0x03000002, 0x800f0800, 0x80e40000, 0xa0550000, /* add oC0, r0, c0.y */
21877 0x0000ffff
21879 static const struct
21881 struct vec3 pos;
21882 D3DCOLOR color;
21884 quad[] =
21886 {{-1.0f, -1.0f, 0.1f}, 0x00ff0000},
21887 {{-1.0f, 1.0f, 0.1f}, 0x0000ff00},
21888 {{ 1.0f, -1.0f, 0.1f}, 0x00ff0000},
21889 {{ 1.0f, 1.0f, 0.1f}, 0x0000ff00},
21891 IDirect3DSurface9 *backbuffer, *rt;
21892 IDirect3DVertexShader9 *vs;
21893 IDirect3DPixelShader9 *ps;
21894 IDirect3DDevice9 *device;
21895 IDirect3D9 *d3d;
21896 ULONG refcount;
21897 D3DCAPS9 caps;
21898 DWORD color;
21899 HWND window;
21900 HRESULT hr;
21902 window = create_window();
21903 d3d = Direct3DCreate9(D3D_SDK_VERSION);
21904 ok(!!d3d, "Failed to create a D3D object.\n");
21905 if (!(device = create_device(d3d, window, window, TRUE)))
21907 skip("Failed to create a D3D device, skipping tests.\n");
21908 goto done;
21911 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
21912 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
21913 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
21915 skip("No ps_3_0 support, skipping dsy tests.\n");
21916 IDirect3DDevice9_Release(device);
21917 goto done;
21920 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
21921 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
21923 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
21924 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
21925 ok(SUCCEEDED(hr), "Failed to create offscreen render target, hr %#x.\n", hr);
21926 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
21927 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
21929 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
21930 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
21931 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
21932 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
21934 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
21935 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
21936 hr = IDirect3DDevice9_SetVertexShader(device, vs);
21937 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
21938 hr = IDirect3DDevice9_SetPixelShader(device, ps);
21939 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
21941 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
21942 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21943 hr = IDirect3DDevice9_BeginScene(device);
21944 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21945 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
21946 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
21947 hr = IDirect3DDevice9_EndScene(device);
21948 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
21950 color = getPixelColor(device, 360, 240);
21951 ok(color_match(color, 0x00ff007f, 1), "Got unexpected color 0x%08x.\n", color);
21953 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
21954 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
21956 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
21957 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21958 hr = IDirect3DDevice9_BeginScene(device);
21959 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21960 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
21961 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
21962 hr = IDirect3DDevice9_EndScene(device);
21963 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
21965 color = getPixelColor(device, 360, 240);
21966 ok(color_match(color, 0x00ff007f, 1), "Got unexpected color 0x%08x.\n", color);
21968 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21969 ok(SUCCEEDED(hr), "Failed to present frame, hr %#x.\n", hr);
21971 IDirect3DSurface9_Release(rt);
21972 IDirect3DSurface9_Release(backbuffer);
21973 IDirect3DVertexShader9_Release(vs);
21974 IDirect3DPixelShader9_Release(ps);
21976 refcount = IDirect3DDevice9_Release(device);
21977 ok(!refcount, "Device has %u references left.\n", refcount);
21978 done:
21979 IDirect3D9_Release(d3d);
21980 DestroyWindow(window);
21983 static void test_evict_bound_resources(void)
21985 IDirect3DVertexBuffer9 *vb;
21986 IDirect3DIndexBuffer9 *ib;
21987 IDirect3DDevice9 *device;
21988 IDirect3D9 *d3d9;
21989 ULONG refcount;
21990 D3DCOLOR color;
21991 HWND window;
21992 void *data;
21993 HRESULT hr;
21995 static const struct
21997 struct vec3 position;
21998 DWORD diffuse;
22000 green_quad[] =
22002 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
22003 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
22004 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
22005 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
22007 static const unsigned short indices[] = {0, 1, 2, 3, 2, 1};
22009 window = create_window();
22010 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
22011 ok(!!d3d9, "Failed to create a D3D object.\n");
22013 if (!(device = create_device(d3d9, window, window, TRUE)))
22015 skip("Failed to create a D3D device.\n");
22016 IDirect3D9_Release(d3d9);
22017 DestroyWindow(window);
22018 return;
22021 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0,
22022 D3DFMT_INDEX16, D3DPOOL_MANAGED, &ib, NULL);
22023 ok(SUCCEEDED(hr), "Failed to create index buffer, hr %#x.\n", hr);
22025 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(green_quad), 0,
22026 D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &vb, NULL);
22027 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
22029 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
22030 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
22031 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
22032 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
22033 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
22034 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
22036 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
22037 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
22039 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(green_quad), &data, 0);
22040 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#x.\n", hr);
22041 memcpy(data, green_quad, sizeof(green_quad));
22042 hr = IDirect3DVertexBuffer9_Unlock(vb);
22043 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#x.\n", hr);
22045 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), &data, 0);
22046 ok(hr == D3D_OK, "Failed to lock index buffer, hr %#x.\n", hr);
22047 memcpy(data, indices, sizeof(indices));
22048 hr = IDirect3DIndexBuffer9_Unlock(ib);
22049 ok(hr == D3D_OK, "Failed to unlock index buffer, hr %#x.\n", hr);
22051 hr = IDirect3DDevice9_SetIndices(device, ib);
22052 ok(hr == D3D_OK, "Failed to set index buffer, hr %#x.\n", hr);
22053 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(*green_quad));
22054 ok(hr == D3D_OK, "Failed to set stream source, hr %#x.\n", hr);
22056 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
22057 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22058 hr = IDirect3DDevice9_BeginScene(device);
22059 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22060 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
22061 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22062 hr = IDirect3DDevice9_EndScene(device);
22063 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22064 color = getPixelColor(device, 320, 240);
22065 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
22067 hr = IDirect3DDevice9_EvictManagedResources(device);
22068 ok(hr == D3D_OK, "Failed to evict managed resources, hr %#x.\n", hr);
22070 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
22071 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22072 hr = IDirect3DDevice9_BeginScene(device);
22073 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22074 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
22075 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22076 hr = IDirect3DDevice9_EndScene(device);
22077 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22078 color = getPixelColor(device, 320, 240);
22079 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
22081 IDirect3DIndexBuffer9_Release(ib);
22082 IDirect3DVertexBuffer9_Release(vb);
22083 refcount = IDirect3DDevice9_Release(device);
22084 ok(!refcount, "Device has %u references left.\n", refcount);
22085 IDirect3D9_Release(d3d9);
22086 DestroyWindow(window);
22089 /* This test shows that 0xffff is valid index in D3D9. */
22090 static void test_max_index16(void)
22092 static const struct vertex
22094 struct vec3 position;
22095 DWORD diffuse;
22097 green_quad[] =
22099 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22100 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22101 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22102 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22104 static const unsigned short indices[] = {0, 1, 2, 0xffff};
22105 static const unsigned int vertex_count = 0xffff + 1;
22107 D3DADAPTER_IDENTIFIER9 identifier;
22108 IDirect3DVertexBuffer9 *vb;
22109 IDirect3DIndexBuffer9 *ib;
22110 IDirect3DDevice9 *device;
22111 struct vertex *vb_data;
22112 IDirect3D9 *d3d9;
22113 ULONG refcount;
22114 D3DCOLOR color;
22115 D3DCAPS9 caps;
22116 HWND window;
22117 void *data;
22118 HRESULT hr;
22119 BOOL warp;
22121 window = create_window();
22122 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
22123 ok(!!d3d9, "Failed to create a D3D object.\n");
22125 hr = IDirect3D9_GetAdapterIdentifier(d3d9, D3DADAPTER_DEFAULT, 0, &identifier);
22126 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
22127 warp = adapter_is_warp(&identifier);
22129 if (!(device = create_device(d3d9, window, window, TRUE)))
22131 skip("Failed to create a D3D device.\n");
22132 IDirect3D9_Release(d3d9);
22133 DestroyWindow(window);
22134 return;
22137 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
22138 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
22139 if (caps.MaxVertexIndex < 0xffff)
22141 skip("Max vertex index is lower than 0xffff (%#x).\n", caps.MaxVertexIndex);
22142 IDirect3DDevice9_Release(device);
22143 IDirect3D9_Release(d3d9);
22144 DestroyWindow(window);
22145 return;
22148 hr = IDirect3DDevice9_CreateVertexBuffer(device, vertex_count * sizeof(*green_quad), 0,
22149 D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &vb, NULL);
22150 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
22152 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0,
22153 D3DFMT_INDEX16, D3DPOOL_MANAGED, &ib, NULL);
22154 ok(SUCCEEDED(hr), "Failed to create index buffer, hr %#x.\n", hr);
22156 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
22157 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
22158 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
22159 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
22160 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
22161 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
22163 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
22164 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
22166 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(green_quad), (void **)&vb_data, 0);
22167 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#x.\n", hr);
22168 vb_data[0] = green_quad[0];
22169 vb_data[1] = green_quad[1];
22170 vb_data[2] = green_quad[2];
22171 vb_data[0xffff] = green_quad[3];
22172 hr = IDirect3DVertexBuffer9_Unlock(vb);
22173 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#x.\n", hr);
22175 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), &data, 0);
22176 ok(hr == D3D_OK, "Failed to lock index buffer, hr %#x.\n", hr);
22177 memcpy(data, indices, sizeof(indices));
22178 hr = IDirect3DIndexBuffer9_Unlock(ib);
22179 ok(hr == D3D_OK, "Failed to unlock index buffer, hr %#x.\n", hr);
22181 hr = IDirect3DDevice9_SetIndices(device, ib);
22182 ok(hr == D3D_OK, "Failed to set index buffer, hr %#x.\n", hr);
22183 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(struct vertex));
22184 ok(hr == D3D_OK, "Failed to set stream source, hr %#x.\n", hr);
22186 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
22187 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22188 hr = IDirect3DDevice9_BeginScene(device);
22189 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22190 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 0, vertex_count, 0, 2);
22191 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22192 hr = IDirect3DDevice9_EndScene(device);
22193 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22194 color = getPixelColor(device, 20, 20);
22195 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
22196 color = getPixelColor(device, 320, 240);
22197 ok(color_match(color, 0x0000ff00, 1) || broken(warp), "Got unexpected color 0x%08x.\n", color);
22198 color = getPixelColor(device, 620, 460);
22199 ok(color_match(color, 0x0000ff00, 1) || broken(warp), "Got unexpected color 0x%08x.\n", color);
22201 IDirect3DIndexBuffer9_Release(ib);
22202 IDirect3DVertexBuffer9_Release(vb);
22203 refcount = IDirect3DDevice9_Release(device);
22204 ok(!refcount, "Device has %u references left.\n", refcount);
22205 IDirect3D9_Release(d3d9);
22206 DestroyWindow(window);
22209 static void test_backbuffer_resize(void)
22211 D3DPRESENT_PARAMETERS present_parameters = {0};
22212 IDirect3DSurface9 *backbuffer;
22213 IDirect3DDevice9 *device;
22214 IDirect3D9 *d3d;
22215 D3DCOLOR color;
22216 ULONG refcount;
22217 HWND window;
22218 HRESULT hr;
22220 static const struct
22222 struct vec3 position;
22223 DWORD diffuse;
22225 quad[] =
22227 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22228 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22229 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22230 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22233 window = create_window();
22234 d3d = Direct3DCreate9(D3D_SDK_VERSION);
22235 ok(!!d3d, "Failed to create a D3D object.\n");
22236 if (!(device = create_device(d3d, window, window, TRUE)))
22238 skip("Failed to create a D3D device.\n");
22239 goto done;
22242 /* Wine d3d9 implementation had a bug which was triggered by a
22243 * SetRenderTarget() call with an unreferenced surface. */
22244 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
22245 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
22246 refcount = IDirect3DSurface9_Release(backbuffer);
22247 ok(!refcount, "Surface has %u references left.\n", refcount);
22248 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
22249 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
22250 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
22251 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
22253 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
22254 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22255 color = getPixelColor(device, 1, 1);
22256 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
22258 present_parameters.BackBufferWidth = 800;
22259 present_parameters.BackBufferHeight = 600;
22260 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
22261 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
22262 present_parameters.hDeviceWindow = NULL;
22263 present_parameters.Windowed = TRUE;
22264 present_parameters.EnableAutoDepthStencil = TRUE;
22265 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
22266 hr = IDirect3DDevice9_Reset(device, &present_parameters);
22267 ok(SUCCEEDED(hr), "Failed to reset, hr %#x.\n", hr);
22269 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
22270 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
22271 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
22272 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
22273 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
22274 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
22275 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
22276 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
22278 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
22279 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
22280 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
22281 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
22282 IDirect3DSurface9_Release(backbuffer);
22284 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
22285 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22286 color = getPixelColor(device, 1, 1);
22287 ok(color == 0x00ffff00, "Got unexpected color 0x%08x.\n", color);
22288 color = getPixelColor(device, 700, 500);
22289 ok(color == 0x00ffff00, "Got unexpected color 0x%08x.\n", color);
22291 hr = IDirect3DDevice9_BeginScene(device);
22292 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22293 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
22294 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22295 hr = IDirect3DDevice9_EndScene(device);
22296 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22297 color = getPixelColor(device, 1, 1);
22298 ok(color == 0x0000ff00, "Got unexpected color 0x%08x.\n", color);
22299 color = getPixelColor(device, 700, 500);
22300 ok(color == 0x0000ff00, "Got unexpected color 0x%08x.\n", color);
22302 refcount = IDirect3DDevice9_Release(device);
22303 ok(!refcount, "Device has %u references left.\n", refcount);
22304 done:
22305 IDirect3D9_Release(d3d);
22306 DestroyWindow(window);
22309 static void test_drawindexedprimitiveup(void)
22311 static const struct vertex
22313 struct vec3 position;
22314 DWORD diffuse;
22316 quad[] =
22318 {{-1.0f, -1.0f, 0.1f}, 0xff00ff00},
22319 {{-1.0f, 1.0f, 0.1f}, 0xff0000ff},
22320 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
22321 {{ 1.0f, 1.0f, 0.1f}, 0xff0000ff},
22323 {{-1.0f, -1.0f, 0.1f}, 0xff0000ff},
22324 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
22325 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
22326 {{ 1.0f, 1.0f, 0.1f}, 0xff00ff00},
22328 static const unsigned short indices[] = {0, 1, 2, 3, 4, 5, 6, 7};
22329 IDirect3DDevice9 *device;
22330 IDirect3D9 *d3d;
22331 ULONG refcount;
22332 D3DCOLOR color;
22333 HWND window;
22334 HRESULT hr;
22336 window = create_window();
22337 d3d = Direct3DCreate9(D3D_SDK_VERSION);
22338 ok(!!d3d, "Failed to create a D3D object.\n");
22340 if (!(device = create_device(d3d, window, window, TRUE)))
22342 skip("Failed to create a D3D device.\n");
22343 IDirect3D9_Release(d3d);
22344 DestroyWindow(window);
22345 return;
22348 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
22349 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
22350 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
22351 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
22352 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
22353 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
22355 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
22356 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
22358 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
22359 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22361 hr = IDirect3DDevice9_BeginScene(device);
22362 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22363 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 4, 4, 2, indices + 4, D3DFMT_INDEX16, quad, sizeof(*quad));
22364 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22365 hr = IDirect3DDevice9_EndScene(device);
22366 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22368 color = getPixelColor(device, 160, 120);
22369 ok(color_match(color, 0x0040bf00, 1), "Got unexpected color 0x%08x.\n", color);
22370 color = getPixelColor(device, 480, 120);
22371 ok(color_match(color, 0x0040bf00, 1), "Got unexpected color 0x%08x.\n", color);
22372 color = getPixelColor(device, 160, 360);
22373 ok(color_match(color, 0x00404080, 1), "Got unexpected color 0x%08x.\n", color);
22374 color = getPixelColor(device, 480, 360);
22375 ok(color_match(color, 0x00bf4000, 1), "Got unexpected color 0x%08x.\n", color);
22377 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
22378 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22380 hr = IDirect3DDevice9_BeginScene(device);
22381 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22382 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 0, 4, 2, indices, D3DFMT_INDEX16, quad, sizeof(*quad));
22383 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22384 hr = IDirect3DDevice9_EndScene(device);
22385 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22387 color = getPixelColor(device, 160, 120);
22388 ok(color_match(color, 0x004000bf, 1), "Got unexpected color 0x%08x.\n", color);
22389 color = getPixelColor(device, 480, 120);
22390 ok(color_match(color, 0x004000bf, 1), "Got unexpected color 0x%08x.\n", color);
22391 color = getPixelColor(device, 160, 360);
22392 ok(color_match(color, 0x00408040, 1), "Got unexpected color 0x%08x.\n", color);
22393 color = getPixelColor(device, 480, 360);
22394 ok(color_match(color, 0x00bf0040, 1), "Got unexpected color 0x%08x.\n", color);
22396 refcount = IDirect3DDevice9_Release(device);
22397 ok(!refcount, "Device has %u references left.\n", refcount);
22398 IDirect3D9_Release(d3d);
22399 DestroyWindow(window);
22402 START_TEST(visual)
22404 D3DADAPTER_IDENTIFIER9 identifier;
22405 IDirect3D9 *d3d;
22406 HRESULT hr;
22408 if (!(d3d = Direct3DCreate9(D3D_SDK_VERSION)))
22410 skip("could not create D3D9 object\n");
22411 return;
22414 memset(&identifier, 0, sizeof(identifier));
22415 hr = IDirect3D9_GetAdapterIdentifier(d3d, 0, 0, &identifier);
22416 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
22417 trace("Driver string: \"%s\"\n", identifier.Driver);
22418 trace("Description string: \"%s\"\n", identifier.Description);
22419 /* Only Windows XP's default VGA driver should have an empty description */
22420 ok(identifier.Description[0] || broken(!strcmp(identifier.Driver, "vga.dll")), "Empty driver description.\n");
22421 trace("Device name string: \"%s\"\n", identifier.DeviceName);
22422 ok(identifier.DeviceName[0], "Empty device name.\n");
22423 trace("Driver version %d.%d.%d.%d\n",
22424 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
22425 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
22427 IDirect3D9_Release(d3d);
22429 test_sanity();
22430 depth_clamp_test();
22431 stretchrect_test();
22432 lighting_test();
22433 test_specular_lighting();
22434 clear_test();
22435 color_fill_test();
22436 fog_test();
22437 test_cube_wrap();
22438 z_range_test();
22439 maxmip_test();
22440 offscreen_test();
22441 ds_size_test();
22442 test_blend();
22443 test_shademode();
22444 srgbtexture_test();
22445 release_buffer_test();
22446 float_texture_test();
22447 g16r16_texture_test();
22448 pixelshader_blending_test();
22449 texture_transform_flags_test();
22450 autogen_mipmap_test();
22451 fixed_function_decl_test();
22452 conditional_np2_repeat_test();
22453 fixed_function_bumpmap_test();
22454 test_pointsize();
22455 tssargtemp_test();
22456 np2_stretch_rect_test();
22457 yuv_color_test();
22458 yuv_layout_test();
22459 zwriteenable_test();
22460 alphatest_test();
22461 viewport_test();
22462 test_constant_clamp_vs();
22463 test_compare_instructions();
22464 test_mova();
22465 loop_index_test();
22466 sincos_test();
22467 sgn_test();
22468 clip_planes_test();
22469 test_vshader_input();
22470 test_vshader_float16();
22471 stream_test();
22472 fog_with_shader_test();
22473 texbem_test();
22474 texdepth_test();
22475 texkill_test();
22476 volume_v16u16_test();
22477 constant_clamp_ps_test();
22478 cnd_test();
22479 dp2add_ps_test();
22480 unbound_sampler_test();
22481 nested_loop_test();
22482 pretransformed_varying_test();
22483 vface_register_test();
22484 test_fragment_coords();
22485 multiple_rendertargets_test();
22486 texop_test();
22487 texop_range_test();
22488 alphareplicate_test();
22489 dp3_alpha_test();
22490 depth_buffer_test();
22491 depth_buffer2_test();
22492 depth_blit_test();
22493 intz_test();
22494 shadow_test();
22495 fp_special_test();
22496 depth_bounds_test();
22497 srgbwrite_format_test();
22498 update_surface_test();
22499 multisample_get_rtdata_test();
22500 zenable_test();
22501 fog_special_test();
22502 volume_srgb_test();
22503 volume_dxt5_test();
22504 add_dirty_rect_test();
22505 multisampled_depth_buffer_test();
22506 resz_test();
22507 stencil_cull_test();
22508 test_per_stage_constant();
22509 test_3dc_formats();
22510 test_fog_interpolation();
22511 test_negative_fixedfunction_fog();
22512 test_position_index();
22513 test_table_fog_zw();
22514 test_signed_formats();
22515 test_multisample_mismatch();
22516 test_texcoordindex();
22517 test_vertex_blending();
22518 test_updatetexture();
22519 test_depthbias();
22520 test_flip();
22521 test_uninitialized_varyings();
22522 test_multisample_init();
22523 test_texture_blending();
22524 test_color_clamping();
22525 test_line_antialiasing_blending();
22526 test_dsy();
22527 test_evict_bound_resources();
22528 test_max_index16();
22529 test_backbuffer_resize();
22530 test_drawindexedprimitiveup();