d3d9/tests: Properly check for mipmap autogeneration support.
[wine.git] / dlls / d3d9 / tests / visual.c
blob55047d0f4b55b27c4bc12ab46f5f0d7aecb9534f
1 /*
2 * Copyright 2005, 2007-2008 Henri Verbeet
3 * Copyright (C) 2007-2013 Stefan Dösinger(for CodeWeavers)
4 * Copyright (C) 2008 Jason Green(for TransGaming)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 /* This test framework allows limited testing of rendering results. Things are rendered, shown on
22 * the framebuffer, read back from there and compared to expected colors.
24 * However, neither d3d nor opengl is guaranteed to be pixel exact, and thus the capability of this test
25 * is rather limited. As a general guideline for adding tests, do not rely on corner pixels. Draw a big enough
26 * area which shows specific behavior(like a quad on the whole screen), and try to get resulting colors with
27 * all bits set or unset in all channels(like pure red, green, blue, white, black). Hopefully everything that
28 * causes visible results in games can be tested in a way that does not depend on pixel exactness
31 #include <math.h>
33 #define COBJMACROS
34 #include <d3d9.h>
35 #include "wine/test.h"
37 struct vec2
39 float x, y;
42 struct vec3
44 float x, y, z;
47 struct vec4
49 float x, y, z, w;
52 static HWND create_window(void)
54 HWND hwnd;
55 RECT rect;
57 SetRect(&rect, 0, 0, 640, 480);
58 AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE);
59 hwnd = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
60 0, 0, rect.right - rect.left, rect.bottom - rect.top, 0, 0, 0, 0);
61 return hwnd;
64 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
66 if (abs((int)(c1 & 0xff) - (int)(c2 & 0xff)) > max_diff) return FALSE;
67 c1 >>= 8; c2 >>= 8;
68 if (abs((int)(c1 & 0xff) - (int)(c2 & 0xff)) > max_diff) return FALSE;
69 c1 >>= 8; c2 >>= 8;
70 if (abs((int)(c1 & 0xff) - (int)(c2 & 0xff)) > max_diff) return FALSE;
71 c1 >>= 8; c2 >>= 8;
72 if (abs((int)(c1 & 0xff) - (int)(c2 & 0xff)) > max_diff) return FALSE;
73 return TRUE;
76 static BOOL adapter_is_warp(const D3DADAPTER_IDENTIFIER9 *identifier)
78 return !strcmp(identifier->Driver, "d3d10warp.dll");
81 /* Locks a given surface and returns the color at (x,y). It's the caller's
82 * responsibility to only pass in lockable surfaces and valid x,y coordinates */
83 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
85 DWORD color;
86 HRESULT hr;
87 D3DSURFACE_DESC desc;
88 RECT rectToLock = {x, y, x+1, y+1};
89 D3DLOCKED_RECT lockedRect;
91 hr = IDirect3DSurface9_GetDesc(surface, &desc);
92 if(FAILED(hr)) /* This is not a test */
94 trace("Can't get the surface description, hr=%08x\n", hr);
95 return 0xdeadbeef;
98 hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
99 if(FAILED(hr)) /* This is not a test */
101 trace("Can't lock the surface, hr=%08x\n", hr);
102 return 0xdeadbeef;
104 switch(desc.Format) {
105 case D3DFMT_A8R8G8B8:
107 color = ((DWORD *) lockedRect.pBits)[0];
108 break;
110 default:
111 trace("Error: unknown surface format: %d\n", desc.Format);
112 color = 0xdeadbeef;
113 break;
115 hr = IDirect3DSurface9_UnlockRect(surface);
116 if(FAILED(hr))
118 trace("Can't unlock the surface, hr=%08x\n", hr);
120 return color;
123 struct surface_readback
125 IDirect3DSurface9 *surface;
126 D3DLOCKED_RECT locked_rect;
129 static void get_rt_readback(IDirect3DSurface9 *surface, struct surface_readback *rb)
131 IDirect3DDevice9 *device;
132 D3DSURFACE_DESC desc;
133 HRESULT hr;
135 memset(rb, 0, sizeof(*rb));
136 hr = IDirect3DSurface9_GetDevice(surface, &device);
137 ok(SUCCEEDED(hr), "Failed to get device, hr %#x.\n", hr);
138 hr = IDirect3DSurface9_GetDesc(surface, &desc);
139 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
140 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, desc.Width, desc.Height,
141 desc.Format, D3DPOOL_SYSTEMMEM, &rb->surface, NULL);
142 if (FAILED(hr) || !rb->surface)
144 trace("Can't create an offscreen plain surface to read the render target data, hr %#x.\n", hr);
145 goto error;
148 hr = IDirect3DDevice9_GetRenderTargetData(device, surface, rb->surface);
149 if (FAILED(hr))
151 trace("Can't read the render target data, hr %#x.\n", hr);
152 goto error;
155 hr = IDirect3DSurface9_LockRect(rb->surface, &rb->locked_rect, NULL, D3DLOCK_READONLY);
156 if (FAILED(hr))
158 trace("Can't lock the offscreen surface, hr %#x.\n", hr);
159 goto error;
161 IDirect3DDevice9_Release(device);
163 return;
165 error:
166 if (rb->surface)
167 IDirect3DSurface9_Release(rb->surface);
168 rb->surface = NULL;
169 IDirect3DDevice9_Release(device);
172 static DWORD get_readback_color(struct surface_readback *rb, unsigned int x, unsigned int y)
174 return rb->locked_rect.pBits
175 ? ((DWORD *)rb->locked_rect.pBits)[y * rb->locked_rect.Pitch / sizeof(DWORD) + x] : 0xdeadbeef;
178 static void release_surface_readback(struct surface_readback *rb)
180 HRESULT hr;
182 if (!rb->surface)
183 return;
184 if (rb->locked_rect.pBits && FAILED(hr = IDirect3DSurface9_UnlockRect(rb->surface)))
185 trace("Can't unlock the offscreen surface, hr %#x.\n", hr);
186 IDirect3DSurface9_Release(rb->surface);
189 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
191 DWORD ret;
192 IDirect3DSurface9 *rt;
193 struct surface_readback rb;
194 HRESULT hr;
196 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
197 if(FAILED(hr))
199 trace("Can't get the render target, hr %#x.\n", hr);
200 return 0xdeadbeed;
203 get_rt_readback(rt, &rb);
204 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
205 * really important for these tests
207 ret = get_readback_color(&rb, x, y) & 0x00ffffff;
208 release_surface_readback(&rb);
210 IDirect3DSurface9_Release(rt);
211 return ret;
214 static IDirect3DDevice9 *create_device(IDirect3D9 *d3d, HWND device_window, HWND focus_window, BOOL windowed)
216 D3DPRESENT_PARAMETERS present_parameters = {0};
217 IDirect3DDevice9 *device;
219 present_parameters.Windowed = windowed;
220 present_parameters.hDeviceWindow = device_window;
221 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
222 present_parameters.BackBufferWidth = 640;
223 present_parameters.BackBufferHeight = 480;
224 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
225 present_parameters.EnableAutoDepthStencil = TRUE;
226 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
228 if (SUCCEEDED(IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
229 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device)))
230 return device;
232 return NULL;
235 static void cleanup_device(IDirect3DDevice9 *device)
237 if (device)
239 D3DPRESENT_PARAMETERS present_parameters;
240 IDirect3DSwapChain9 *swapchain;
241 ULONG ref;
243 IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
244 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
245 IDirect3DSwapChain9_Release(swapchain);
246 ref = IDirect3DDevice9_Release(device);
247 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
248 DestroyWindow(present_parameters.hDeviceWindow);
252 static void test_sanity(void)
254 IDirect3DDevice9 *device;
255 IDirect3D9 *d3d;
256 D3DCOLOR color;
257 ULONG refcount;
258 HWND window;
259 HRESULT hr;
261 window = create_window();
262 d3d = Direct3DCreate9(D3D_SDK_VERSION);
263 ok(!!d3d, "Failed to create a D3D object.\n");
264 if (!(device = create_device(d3d, window, window, TRUE)))
266 skip("Failed to create a D3D device, skipping tests.\n");
267 goto done;
270 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
271 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
272 color = getPixelColor(device, 1, 1);
273 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
275 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
276 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
278 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
279 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
280 color = getPixelColor(device, 639, 479);
281 ok(color == 0x0000ddee, "Got unexpected color 0x%08x.\n", color);
283 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
284 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
286 refcount = IDirect3DDevice9_Release(device);
287 ok(!refcount, "Device has %u references left.\n", refcount);
288 done:
289 IDirect3D9_Release(d3d);
290 DestroyWindow(window);
293 static void lighting_test(void)
295 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
296 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
297 IDirect3DDevice9 *device;
298 D3DMATERIAL9 material;
299 IDirect3D9 *d3d;
300 D3DCOLOR color;
301 ULONG refcount;
302 HWND window;
303 HRESULT hr;
304 unsigned int i;
306 static const D3DMATRIX mat =
308 1.0f, 0.0f, 0.0f, 0.0f,
309 0.0f, 1.0f, 0.0f, 0.0f,
310 0.0f, 0.0f, 1.0f, 0.0f,
311 0.0f, 0.0f, 0.0f, 1.0f,
312 }}},
313 mat_singular =
315 1.0f, 0.0f, 1.0f, 0.0f,
316 0.0f, 1.0f, 0.0f, 0.0f,
317 1.0f, 0.0f, 1.0f, 0.0f,
318 0.0f, 0.0f, 0.5f, 1.0f,
319 }}},
320 mat_transf =
322 0.0f, 0.0f, 1.0f, 0.0f,
323 0.0f, 1.0f, 0.0f, 0.0f,
324 -1.0f, 0.0f, 0.0f, 0.0f,
325 10.f, 10.0f, 10.0f, 1.0f,
326 }}},
327 mat_nonaffine =
329 1.0f, 0.0f, 0.0f, 0.0f,
330 0.0f, 1.0f, 0.0f, 0.0f,
331 0.0f, 0.0f, 1.0f, -1.0f,
332 10.f, 10.0f, 10.0f, 0.0f,
333 }}};
334 static const struct
336 struct vec3 position;
337 DWORD diffuse;
339 unlitquad[] =
341 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
342 {{-1.0f, 0.0f, 0.1f}, 0xffff0000},
343 {{ 0.0f, 0.0f, 0.1f}, 0xffff0000},
344 {{ 0.0f, -1.0f, 0.1f}, 0xffff0000},
346 litquad[] =
348 {{-1.0f, 0.0f, 0.1f}, 0xff00ff00},
349 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
350 {{ 0.0f, 1.0f, 0.1f}, 0xff00ff00},
351 {{ 0.0f, 0.0f, 0.1f}, 0xff00ff00},
353 lighting_test[] =
355 {{-1.0f, -1.0f, 0.1f}, 0x8000ff00},
356 {{ 1.0f, -1.0f, 0.1f}, 0x80000000},
357 {{-1.0f, 1.0f, 0.1f}, 0x8000ff00},
358 {{ 1.0f, 1.0f, 0.1f}, 0x80000000},
360 static const struct
362 struct vec3 position;
363 struct vec3 normal;
364 DWORD diffuse;
366 unlitnquad[] =
368 {{0.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
369 {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
370 {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
371 {{1.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
373 litnquad[] =
375 {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
376 {{0.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
377 {{1.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
378 {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
380 nquad[] =
382 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
383 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
384 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
385 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
387 rotatedquad[] =
389 {{-10.0f, -11.0f, 11.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
390 {{-10.0f, -9.0f, 11.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
391 {{-10.0f, -9.0f, 9.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
392 {{-10.0f, -11.0f, 9.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
394 translatedquad[] =
396 {{-11.0f, -11.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
397 {{-11.0f, -9.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
398 {{ -9.0f, -9.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
399 {{ -9.0f, -11.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
401 static const WORD indices[] = {0, 1, 2, 2, 3, 0};
402 static const struct
404 const D3DMATRIX *world_matrix;
405 const void *quad;
406 unsigned int size;
407 DWORD expected;
408 const char *message;
410 tests[] =
412 {&mat, nquad, sizeof(nquad[0]), 0x000000ff, "Lit quad with light"},
413 {&mat_singular, nquad, sizeof(nquad[0]), 0x000000ff, "Lit quad with singular world matrix"},
414 {&mat_transf, rotatedquad, sizeof(rotatedquad[0]), 0x000000ff, "Lit quad with transformation matrix"},
415 {&mat_nonaffine, translatedquad, sizeof(translatedquad[0]), 0x00000000, "Lit quad with non-affine matrix"},
418 window = create_window();
419 d3d = Direct3DCreate9(D3D_SDK_VERSION);
420 ok(!!d3d, "Failed to create a D3D object.\n");
421 if (!(device = create_device(d3d, window, window, TRUE)))
423 skip("Failed to create a D3D device, skipping tests.\n");
424 goto done;
427 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
428 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
430 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &mat);
431 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
432 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
433 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
434 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
435 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
436 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
437 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
438 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
439 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
440 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
441 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
442 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
443 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
444 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
445 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
447 hr = IDirect3DDevice9_SetFVF(device, fvf);
448 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
450 hr = IDirect3DDevice9_BeginScene(device);
451 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
453 /* No lights are defined... That means, lit vertices should be entirely black */
454 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
455 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
456 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
457 2, indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
458 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
460 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
461 ok(SUCCEEDED(hr), "Failed to enable lighting, hr %#x.\n", hr);
462 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
463 2, indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
464 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
466 hr = IDirect3DDevice9_SetFVF(device, nfvf);
467 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
469 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
470 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
471 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
472 2, indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
473 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
475 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
476 ok(SUCCEEDED(hr), "Failed to enable lighting, hr %#x.\n", hr);
477 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
478 2, indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
479 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
481 hr = IDirect3DDevice9_EndScene(device);
482 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
484 color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
485 ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
486 color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
487 ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
488 color = getPixelColor(device, 480, 360); /* Lower left quad - unlit with normals */
489 ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
490 color = getPixelColor(device, 480, 120); /* Upper left quad - lit with normals */
491 ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
493 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
495 hr = IDirect3DDevice9_LightEnable(device, 0, TRUE);
496 ok(SUCCEEDED(hr), "Failed to enable light 0, hr %#x.\n", hr);
498 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
500 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, tests[i].world_matrix);
501 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
503 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
504 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
506 hr = IDirect3DDevice9_BeginScene(device);
507 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
509 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
510 2, indices, D3DFMT_INDEX16, tests[i].quad, tests[i].size);
511 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
513 hr = IDirect3DDevice9_EndScene(device);
514 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
516 color = getPixelColor(device, 320, 240);
517 ok(color == tests[i].expected, "%s has color 0x%08x.\n", tests[i].message, color);
520 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
521 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
522 hr = IDirect3DDevice9_LightEnable(device, 0, FALSE);
523 ok(SUCCEEDED(hr), "Failed to disable light 0, hr %#x.\n", hr);
525 memset(&material, 0, sizeof(material));
526 material.Diffuse.r = 0.0;
527 material.Diffuse.g = 0.0;
528 material.Diffuse.b = 0.0;
529 material.Diffuse.a = 1.0;
530 material.Ambient.r = 0.0;
531 material.Ambient.g = 0.0;
532 material.Ambient.b = 0.0;
533 material.Ambient.a = 0.0;
534 material.Specular.r = 0.0;
535 material.Specular.g = 0.0;
536 material.Specular.b = 0.0;
537 material.Specular.a = 0.0;
538 material.Emissive.r = 0.0;
539 material.Emissive.g = 0.0;
540 material.Emissive.b = 0.0;
541 material.Emissive.a = 0.0;
542 material.Power = 0.0;
543 hr = IDirect3DDevice9_SetMaterial(device, &material);
544 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
546 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
547 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
548 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
549 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
551 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
552 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
553 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
554 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
556 hr = IDirect3DDevice9_BeginScene(device);
557 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
559 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
560 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
561 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
562 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
564 hr = IDirect3DDevice9_EndScene(device);
565 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
567 color = getPixelColor(device, 320, 240);
568 ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
569 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
571 refcount = IDirect3DDevice9_Release(device);
572 ok(!refcount, "Device has %u references left.\n", refcount);
573 done:
574 IDirect3D9_Release(d3d);
575 DestroyWindow(window);
578 static void test_specular_lighting(void)
580 static const unsigned int vertices_side = 5;
581 const unsigned int indices_count = (vertices_side - 1) * (vertices_side - 1) * 2 * 3;
582 static const DWORD fvf = D3DFVF_XYZ | D3DFVF_NORMAL;
583 static const D3DMATRIX mat =
585 1.0f, 0.0f, 0.0f, 0.0f,
586 0.0f, 1.0f, 0.0f, 0.0f,
587 0.0f, 0.0f, 1.0f, 0.0f,
588 0.0f, 0.0f, 0.0f, 1.0f,
589 }}};
590 static const D3DLIGHT9 directional =
592 D3DLIGHT_DIRECTIONAL,
593 {0.0f, 0.0f, 0.0f, 0.0f},
594 {1.0f, 1.0f, 1.0f, 0.0f},
595 {0.0f, 0.0f, 0.0f, 0.0f},
596 {0.0f, 0.0f, 0.0f},
597 {0.0f, 0.0f, 1.0f},
599 point =
601 D3DLIGHT_POINT,
602 {0.0f, 0.0f, 0.0f, 0.0f},
603 {1.0f, 1.0f, 1.0f, 0.0f},
604 {0.0f, 0.0f, 0.0f, 0.0f},
605 {0.0f, 0.0f, 0.0f},
606 {0.0f, 0.0f, 0.0f},
607 100.0f,
608 0.0f,
609 0.0f, 0.0f, 1.0f,
611 spot =
613 D3DLIGHT_SPOT,
614 {0.0f, 0.0f, 0.0f, 0.0f},
615 {1.0f, 1.0f, 1.0f, 0.0f},
616 {0.0f, 0.0f, 0.0f, 0.0f},
617 {0.0f, 0.0f, 0.0f},
618 {0.0f, 0.0f, 1.0f},
619 100.0f,
620 1.0f,
621 0.0f, 0.0f, 1.0f,
622 M_PI / 12.0f, M_PI / 3.0f
624 /* The chosen range value makes the test fail when using a manhattan
625 * distance metric vs the correct euclidean distance. */
626 point_range =
628 D3DLIGHT_POINT,
629 {0.0f, 0.0f, 0.0f, 0.0f},
630 {1.0f, 1.0f, 1.0f, 0.0f},
631 {0.0f, 0.0f, 0.0f, 0.0f},
632 {0.0f, 0.0f, 0.0f},
633 {0.0f, 0.0f, 0.0f},
634 1.2f,
635 0.0f,
636 0.0f, 0.0f, 1.0f,
638 point_side =
640 D3DLIGHT_POINT,
641 {0.0f, 0.0f, 0.0f, 0.0f},
642 {1.0f, 1.0f, 1.0f, 0.0f},
643 {0.0f, 0.0f, 0.0f, 0.0f},
644 {-1.1f, 0.0f, 1.1f},
645 {0.0f, 0.0f, 0.0f},
646 100.0f,
647 0.0f,
648 0.0f, 0.0f, 1.0f,
650 static const struct expected_color
652 unsigned int x, y;
653 D3DCOLOR color;
655 expected_directional[] =
657 {160, 120, 0x00ffffff},
658 {320, 120, 0x00ffffff},
659 {480, 120, 0x00ffffff},
660 {160, 240, 0x00ffffff},
661 {320, 240, 0x00ffffff},
662 {480, 240, 0x00ffffff},
663 {160, 360, 0x00ffffff},
664 {320, 360, 0x00ffffff},
665 {480, 360, 0x00ffffff},
667 expected_directional_local[] =
669 {160, 120, 0x003c3c3c},
670 {320, 120, 0x00717171},
671 {480, 120, 0x003c3c3c},
672 {160, 240, 0x00717171},
673 {320, 240, 0x00ffffff},
674 {480, 240, 0x00717171},
675 {160, 360, 0x003c3c3c},
676 {320, 360, 0x00717171},
677 {480, 360, 0x003c3c3c},
679 expected_point[] =
681 {160, 120, 0x00282828},
682 {320, 120, 0x005a5a5a},
683 {480, 120, 0x00282828},
684 {160, 240, 0x005a5a5a},
685 {320, 240, 0x00ffffff},
686 {480, 240, 0x005a5a5a},
687 {160, 360, 0x00282828},
688 {320, 360, 0x005a5a5a},
689 {480, 360, 0x00282828},
691 expected_point_local[] =
693 {160, 120, 0x00000000},
694 {320, 120, 0x00070707},
695 {480, 120, 0x00000000},
696 {160, 240, 0x00070707},
697 {320, 240, 0x00ffffff},
698 {480, 240, 0x00070707},
699 {160, 360, 0x00000000},
700 {320, 360, 0x00070707},
701 {480, 360, 0x00000000},
703 expected_spot[] =
705 {160, 120, 0x00000000},
706 {320, 120, 0x00141414},
707 {480, 120, 0x00000000},
708 {160, 240, 0x00141414},
709 {320, 240, 0x00ffffff},
710 {480, 240, 0x00141414},
711 {160, 360, 0x00000000},
712 {320, 360, 0x00141414},
713 {480, 360, 0x00000000},
715 expected_spot_local[] =
717 {160, 120, 0x00000000},
718 {320, 120, 0x00020202},
719 {480, 120, 0x00000000},
720 {160, 240, 0x00020202},
721 {320, 240, 0x00ffffff},
722 {480, 240, 0x00020202},
723 {160, 360, 0x00000000},
724 {320, 360, 0x00020202},
725 {480, 360, 0x00000000},
727 expected_point_range[] =
729 {160, 120, 0x00000000},
730 {320, 120, 0x005a5a5a},
731 {480, 120, 0x00000000},
732 {160, 240, 0x005a5a5a},
733 {320, 240, 0x00ffffff},
734 {480, 240, 0x005a5a5a},
735 {160, 360, 0x00000000},
736 {320, 360, 0x005a5a5a},
737 {480, 360, 0x00000000},
739 expected_point_side[] =
741 {160, 120, 0x00000000},
742 {320, 120, 0x00000000},
743 {480, 120, 0x00000000},
744 {160, 240, 0x00000000},
745 {320, 240, 0x00000000},
746 {480, 240, 0x00000000},
747 {160, 360, 0x00000000},
748 {320, 360, 0x00000000},
749 {480, 360, 0x00000000},
751 static const struct
753 const D3DLIGHT9 *light;
754 BOOL local_viewer;
755 float specular_power;
756 const struct expected_color *expected;
757 unsigned int expected_count;
759 tests[] =
761 {&directional, FALSE, 30.0f, expected_directional,
762 sizeof(expected_directional) / sizeof(expected_directional[0])},
763 {&directional, TRUE, 30.0f, expected_directional_local,
764 sizeof(expected_directional_local) / sizeof(expected_directional_local[0])},
765 {&point, FALSE, 30.0f, expected_point,
766 sizeof(expected_point) / sizeof(expected_point[0])},
767 {&point, TRUE, 30.0f, expected_point_local,
768 sizeof(expected_point_local) / sizeof(expected_point_local[0])},
769 {&spot, FALSE, 30.0f, expected_spot,
770 sizeof(expected_spot) / sizeof(expected_spot[0])},
771 {&spot, TRUE, 30.0f, expected_spot_local,
772 sizeof(expected_spot_local) / sizeof(expected_spot_local[0])},
773 {&point_range, FALSE, 30.0f, expected_point_range,
774 sizeof(expected_point_range) / sizeof(expected_point_range[0])},
775 {&point_side, TRUE, 0.0f, expected_point_side,
776 sizeof(expected_point_side) / sizeof(expected_point_side[0])},
778 IDirect3DDevice9 *device;
779 D3DMATERIAL9 material;
780 IDirect3D9 *d3d;
781 D3DCOLOR color;
782 ULONG refcount;
783 HWND window;
784 HRESULT hr;
785 unsigned int i, j, x, y;
786 struct
788 struct vec3 position;
789 struct vec3 normal;
790 } *quad;
791 WORD *indices;
793 quad = HeapAlloc(GetProcessHeap(), 0, vertices_side * vertices_side * sizeof(*quad));
794 indices = HeapAlloc(GetProcessHeap(), 0, indices_count * sizeof(*indices));
795 for (i = 0, y = 0; y < vertices_side; ++y)
797 for (x = 0; x < vertices_side; ++x)
799 quad[i].position.x = x * 2.0f / (vertices_side - 1) - 1.0f;
800 quad[i].position.y = y * 2.0f / (vertices_side - 1) - 1.0f;
801 quad[i].position.z = 1.0f;
802 quad[i].normal.x = 0.0f;
803 quad[i].normal.y = 0.0f;
804 quad[i++].normal.z = -1.0f;
807 for (i = 0, y = 0; y < (vertices_side - 1); ++y)
809 for (x = 0; x < (vertices_side - 1); ++x)
811 indices[i++] = y * vertices_side + x + 1;
812 indices[i++] = y * vertices_side + x;
813 indices[i++] = (y + 1) * vertices_side + x;
814 indices[i++] = y * vertices_side + x + 1;
815 indices[i++] = (y + 1) * vertices_side + x;
816 indices[i++] = (y + 1) * vertices_side + x + 1;
820 window = create_window();
821 d3d = Direct3DCreate9(D3D_SDK_VERSION);
822 ok(!!d3d, "Failed to create a D3D object.\n");
823 if (!(device = create_device(d3d, window, window, TRUE)))
825 skip("Failed to create a D3D device, skipping tests.\n");
826 goto done;
829 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
830 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
831 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
832 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
833 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
834 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
835 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
836 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
837 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
838 ok(SUCCEEDED(hr), "Failed to disable z test, hr %#x.\n", hr);
839 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
840 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
842 hr = IDirect3DDevice9_SetFVF(device, fvf);
843 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
845 hr = IDirect3DDevice9_LightEnable(device, 0, TRUE);
846 ok(SUCCEEDED(hr), "Failed to enable light 0, hr %#x.\n", hr);
847 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
848 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#x.\n", hr);
850 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
852 hr = IDirect3DDevice9_SetLight(device, 0, tests[i].light);
853 ok(SUCCEEDED(hr), "Failed to set light parameters, hr %#x.\n", hr);
855 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LOCALVIEWER, tests[i].local_viewer);
856 ok(SUCCEEDED(hr), "Failed to set local viewer state, hr %#x.\n", hr);
858 memset(&material, 0, sizeof(material));
859 material.Specular.r = 1.0f;
860 material.Specular.g = 1.0f;
861 material.Specular.b = 1.0f;
862 material.Specular.a = 1.0f;
863 material.Power = tests[i].specular_power;
864 hr = IDirect3DDevice9_SetMaterial(device, &material);
865 ok(SUCCEEDED(hr), "Failed to set material, hr %#x.\n", hr);
867 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
868 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
870 hr = IDirect3DDevice9_BeginScene(device);
871 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
873 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST,
874 0, vertices_side * vertices_side, indices_count / 3, indices,
875 D3DFMT_INDEX16, quad, sizeof(quad[0]));
876 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
878 hr = IDirect3DDevice9_EndScene(device);
879 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
881 for (j = 0; j < tests[i].expected_count; ++j)
883 color = getPixelColor(device, tests[i].expected[j].x, tests[i].expected[j].y);
884 ok(color_match(color, tests[i].expected[j].color, 1),
885 "Expected color 0x%08x at location (%u, %u), got 0x%08x, case %u.\n",
886 tests[i].expected[j].color, tests[i].expected[j].x,
887 tests[i].expected[j].y, color, i);
891 refcount = IDirect3DDevice9_Release(device);
892 ok(!refcount, "Device has %u references left.\n", refcount);
893 done:
894 IDirect3D9_Release(d3d);
895 DestroyWindow(window);
896 HeapFree(GetProcessHeap(), 0, indices);
897 HeapFree(GetProcessHeap(), 0, quad);
900 static void clear_test(void)
902 static const D3DMATRIX mat =
904 1.0f, 0.0f, 0.0f, 0.0f,
905 0.0f, 1.0f, 0.0f, 0.0f,
906 0.0f, 0.0f, 1.0f, 0.0f,
907 0.0f, 0.0f, 0.0f, 1.0f,
908 }}};
909 static const struct
911 struct vec3 position;
912 DWORD diffuse;
914 quad[] =
916 {{-1.0f, -1.0f, 0.1f}, 0xff7f7f7f},
917 {{ 1.0f, -1.0f, 0.1f}, 0xff7f7f7f},
918 {{-1.0f, 1.0f, 0.1f}, 0xff7f7f7f},
919 {{ 1.0f, 1.0f, 0.1f}, 0xff7f7f7f},
921 IDirect3DSurface9 *surface0, *surface1, *backbuffer;
922 IDirect3DTexture9 *texture;
923 HRESULT hr;
924 D3DRECT rect[2];
925 D3DRECT rect_negneg;
926 DWORD color;
927 D3DVIEWPORT9 old_vp, vp;
928 RECT scissor;
929 DWORD oldColorWrite;
930 BOOL invalid_clear_failed = FALSE, srgb_supported;
931 IDirect3DDevice9 *device;
932 IDirect3D9 *d3d;
933 ULONG refcount;
934 HWND window;
936 window = create_window();
937 d3d = Direct3DCreate9(D3D_SDK_VERSION);
938 ok(!!d3d, "Failed to create a D3D object.\n");
939 if (!(device = create_device(d3d, window, window, TRUE)))
941 skip("Failed to create a D3D device, skipping tests.\n");
942 goto done;
945 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
946 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
948 /* Positive x, negative y */
949 rect[0].x1 = 0;
950 rect[0].y1 = 480;
951 rect[0].x2 = 320;
952 rect[0].y2 = 240;
954 /* Positive x, positive y */
955 rect[1].x1 = 0;
956 rect[1].y1 = 0;
957 rect[1].x2 = 320;
958 rect[1].y2 = 240;
959 /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
960 * returns D3D_OK, but ignores the rectangle silently
962 hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
963 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
964 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
966 /* negative x, negative y */
967 rect_negneg.x1 = 640;
968 rect_negneg.y1 = 240;
969 rect_negneg.x2 = 320;
970 rect_negneg.y2 = 0;
971 hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
972 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
973 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
975 color = getPixelColor(device, 160, 360); /* lower left quad */
976 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
977 color = getPixelColor(device, 160, 120); /* upper left quad */
978 if(invalid_clear_failed) {
979 /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
980 ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
981 } else {
982 /* If the negative rectangle was dropped silently, the correct ones are cleared */
983 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
985 color = getPixelColor(device, 480, 360); /* lower right quad */
986 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
987 color = getPixelColor(device, 480, 120); /* upper right quad */
988 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
990 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
992 /* Hack to work around a nvidia windows driver bug. The clear below is supposed to
993 * clear the red quad in the top left part of the render target. For some reason it
994 * doesn't work if the clear color is 0xffffffff on some versions of the Nvidia Windows
995 * driver(tested on 8.17.12.5896, Win7). A clear with a different color works around
996 * this bug and fixes the clear with the white color. Even 0xfeffffff works, but let's
997 * pick some obvious value
999 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbabe, 0.0, 0);
1000 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1002 /* Test how the viewport affects clears */
1003 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1004 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1005 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
1006 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
1008 vp.X = 160;
1009 vp.Y = 120;
1010 vp.Width = 160;
1011 vp.Height = 120;
1012 vp.MinZ = 0.0;
1013 vp.MaxZ = 1.0;
1014 hr = IDirect3DDevice9_SetViewport(device, &vp);
1015 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
1016 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1017 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1019 vp.X = 320;
1020 vp.Y = 240;
1021 vp.Width = 320;
1022 vp.Height = 240;
1023 vp.MinZ = 0.0;
1024 vp.MaxZ = 1.0;
1025 hr = IDirect3DDevice9_SetViewport(device, &vp);
1026 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
1027 rect[0].x1 = 160;
1028 rect[0].y1 = 120;
1029 rect[0].x2 = 480;
1030 rect[0].y2 = 360;
1031 hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1032 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1034 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
1035 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
1037 color = getPixelColor(device, 158, 118);
1038 ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
1039 color = getPixelColor(device, 162, 118);
1040 ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
1041 color = getPixelColor(device, 158, 122);
1042 ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
1043 color = getPixelColor(device, 162, 122);
1044 ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
1046 color = getPixelColor(device, 318, 238);
1047 ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
1048 color = getPixelColor(device, 322, 238);
1049 ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
1050 color = getPixelColor(device, 318, 242);
1051 ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
1052 color = getPixelColor(device, 322, 242);
1053 ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
1055 color = getPixelColor(device, 478, 358);
1056 ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
1057 color = getPixelColor(device, 482, 358);
1058 ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
1059 color = getPixelColor(device, 478, 362);
1060 ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
1061 color = getPixelColor(device, 482, 362);
1062 ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
1064 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1066 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1067 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1069 SetRect(&scissor, 160, 120, 480, 360);
1070 hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
1071 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
1072 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
1073 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
1075 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1076 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1077 hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1078 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1080 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
1081 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
1083 color = getPixelColor(device, 158, 118);
1084 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
1085 color = getPixelColor(device, 162, 118);
1086 ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
1087 color = getPixelColor(device, 158, 122);
1088 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
1089 color = getPixelColor(device, 162, 122);
1090 ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
1092 color = getPixelColor(device, 158, 358);
1093 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
1094 color = getPixelColor(device, 162, 358);
1095 ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
1096 color = getPixelColor(device, 158, 358);
1097 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
1098 color = getPixelColor(device, 162, 362);
1099 ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
1101 color = getPixelColor(device, 478, 118);
1102 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
1103 color = getPixelColor(device, 478, 122);
1104 ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
1105 color = getPixelColor(device, 482, 122);
1106 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
1107 color = getPixelColor(device, 482, 358);
1108 ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
1110 color = getPixelColor(device, 478, 358);
1111 ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
1112 color = getPixelColor(device, 478, 362);
1113 ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
1114 color = getPixelColor(device, 482, 358);
1115 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
1116 color = getPixelColor(device, 482, 362);
1117 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
1119 color = getPixelColor(device, 318, 238);
1120 ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
1121 color = getPixelColor(device, 318, 242);
1122 ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
1123 color = getPixelColor(device, 322, 238);
1124 ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
1125 color = getPixelColor(device, 322, 242);
1126 ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
1128 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1130 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
1131 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1132 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
1133 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
1135 /* Same nvidia windows driver trouble with white clears as earlier in the same test */
1136 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbeef, 0.0, 0);
1137 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1139 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1140 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1142 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
1143 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
1145 /* Colorwriteenable does not affect the clear */
1146 color = getPixelColor(device, 320, 240);
1147 ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
1149 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1151 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
1152 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1154 rect[0].x1 = 0;
1155 rect[0].y1 = 0;
1156 rect[0].x2 = 640;
1157 rect[0].y2 = 480;
1158 hr = IDirect3DDevice9_Clear(device, 0, rect, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
1159 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1161 color = getPixelColor(device, 320, 240);
1162 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), 1),
1163 "Clear with count = 0, rect != NULL has color %08x\n", color);
1165 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1167 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1168 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1169 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1170 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1172 color = getPixelColor(device, 320, 240);
1173 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1174 "Clear with count = 1, rect = NULL has color %08x\n", color);
1176 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1178 /* Test D3DRS_SRGBWRITEENABLE interactions with clears. */
1179 srgb_supported = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
1180 D3DUSAGE_QUERY_SRGBWRITE, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8));
1181 trace("sRGB writing to D3DFMT_A8R8G8B8 is %ssupported.\n", srgb_supported ? "" : "not ");
1182 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1183 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
1185 color = getPixelColor(device, 320, 240);
1186 ok(color_match(color, 0x007f7f7f, 1), "Clear has color %08x.\n", color);
1188 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
1189 ok(SUCCEEDED(hr), "Failed to enable sRGB write, hr %#x.\n", hr);
1191 /* Draw something to make sure the SRGBWRITEENABLE setting is applied. */
1192 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
1193 ok(SUCCEEDED(hr), "Failed to set world matrix, hr %#x.\n", hr);
1194 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
1195 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
1196 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
1197 ok(SUCCEEDED(hr), "Failed to disable z test, hr %#x.\n", hr);
1198 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1199 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
1200 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
1201 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#x.\n", hr);
1202 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
1203 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
1204 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1205 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
1206 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1207 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1208 hr = IDirect3DDevice9_BeginScene(device);
1209 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1210 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad));
1211 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1212 hr = IDirect3DDevice9_EndScene(device);
1213 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1215 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1216 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
1218 color = getPixelColor(device, 320, 240);
1219 ok(color_match(color, 0x00bbbbbb, 1), "Clear has color %08x.\n", color);
1221 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
1222 ok(SUCCEEDED(hr), "Failed to disable sRGB write, hr %#x.\n", hr);
1224 /* Switching to a new render target seems to be enough to make Windows pick
1225 * up on the changed render state. */
1226 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 2, D3DUSAGE_RENDERTARGET,
1227 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
1228 ok(SUCCEEDED(hr), "Failed to create the offscreen render target, hr %#x.\n", hr);
1229 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1230 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
1231 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface0);
1232 ok(SUCCEEDED(hr), "Failed to get offscreen surface, hr %#x.\n", hr);
1233 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface0);
1234 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1236 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1237 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
1239 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1240 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1242 hr = IDirect3DDevice9_StretchRect(device, surface0, NULL, backbuffer, NULL, D3DTEXF_NONE);
1243 ok(SUCCEEDED(hr), "Failed to blit surface, hr %#x.\n", hr);
1245 color = getPixelColor(device, 64, 64);
1246 ok(color_match(color, 0x007f7f7f, 1), "Clear has color %08x.\n", color);
1248 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
1249 ok(SUCCEEDED(hr), "Failed to enable sRGB write, hr %#x.\n", hr);
1251 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface0);
1252 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1254 hr = IDirect3DDevice9_BeginScene(device);
1255 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1256 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad));
1257 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1258 hr = IDirect3DDevice9_EndScene(device);
1259 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1261 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1262 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
1264 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1265 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1267 hr = IDirect3DDevice9_StretchRect(device, surface0, NULL, backbuffer, NULL, D3DTEXF_NONE);
1268 ok(SUCCEEDED(hr), "Failed to blit surface, hr %#x.\n", hr);
1270 color = getPixelColor(device, 320, 240);
1271 ok(color_match(color, 0x00bbbbbb, 1), "Clear has color %08x.\n", color);
1273 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
1274 ok(SUCCEEDED(hr), "Failed to disable sRGB write, hr %#x.\n", hr);
1275 /* Switching to another surface of the same texture is also enough to make
1276 * the setting "stick". */
1277 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface1);
1278 ok(SUCCEEDED(hr), "Failed to get offscreen surface, hr %#x.\n", hr);
1279 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface1);
1280 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1282 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1283 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
1285 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1286 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1288 hr = IDirect3DDevice9_StretchRect(device, surface1, NULL, backbuffer, NULL, D3DTEXF_NONE);
1289 ok(SUCCEEDED(hr), "Failed to blit surface, hr %#x.\n", hr);
1291 color = getPixelColor(device, 320, 240);
1292 ok(color_match(color, 0x007f7f7f, 1), "Clear has color %08x.\n", color);
1294 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1296 IDirect3DSurface9_Release(surface1);
1297 IDirect3DSurface9_Release(surface0);
1298 IDirect3DSurface9_Release(backbuffer);
1299 IDirect3DTexture9_Release(texture);
1300 refcount = IDirect3DDevice9_Release(device);
1301 ok(!refcount, "Device has %u references left.\n", refcount);
1302 done:
1303 IDirect3D9_Release(d3d);
1304 DestroyWindow(window);
1307 static void color_fill_test(void)
1309 IDirect3DSurface9 *surface;
1310 IDirect3DTexture9 *texture;
1311 D3DCOLOR fill_color, color;
1312 DWORD fill_a, expected_a;
1313 IDirect3DDevice9 *device;
1314 IDirect3D9 *d3d;
1315 ULONG refcount;
1316 HWND window;
1317 HRESULT hr;
1318 static const struct
1320 D3DPOOL pool;
1321 DWORD usage;
1322 HRESULT hr;
1324 resource_types[] =
1326 {D3DPOOL_DEFAULT, 0, D3DERR_INVALIDCALL},
1327 {D3DPOOL_DEFAULT, D3DUSAGE_DYNAMIC, D3DERR_INVALIDCALL},
1328 {D3DPOOL_DEFAULT, D3DUSAGE_RENDERTARGET, D3D_OK},
1329 {D3DPOOL_SYSTEMMEM, 0, D3DERR_INVALIDCALL},
1330 {D3DPOOL_MANAGED, 0, D3DERR_INVALIDCALL},
1331 {D3DPOOL_SCRATCH, 0, D3DERR_INVALIDCALL},
1333 static const struct
1335 D3DFORMAT format;
1336 const char *name;
1337 enum
1339 CHECK_FILL_VALUE = 0x1,
1340 BLOCKS = 0x2,
1341 } flags;
1342 DWORD fill_value;
1344 formats[] =
1346 {D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8", CHECK_FILL_VALUE, 0xdeadbeef},
1347 /* D3DFMT_X8R8G8B8 either set X = A or X = 0, depending on the driver. */
1348 {D3DFMT_R5G6B5, "D3DFMT_R5G6B5", CHECK_FILL_VALUE, 0xadfdadfd},
1349 {D3DFMT_G16R16, "D3DFMT_G16R16", CHECK_FILL_VALUE, 0xbebeadad},
1350 /* Real hardware reliably fills the surface with the blue channel but
1351 * the testbot fills it with 0x00. Wine incorrectly uses the alpha
1352 * channel. Don't bother checking the result because P8 surfaces are
1353 * essentially useless in d3d9. */
1354 {D3DFMT_P8, "D3DFMT_P8", 0, 0xefefefef},
1355 /* Windows drivers produce different results for these formats.
1356 * No driver produces a YUV value that matches the input RGB
1357 * value, and no driver produces a proper DXT compression block.
1359 * Even the clear value 0 does not reliably produce a fill value
1360 * that will return vec4(0.0, 0.0, 0.0, 0.0) when sampled.
1362 * The YUV tests are disabled because they produce a driver-dependent
1363 * result on Wine.
1364 * {D3DFMT_YUY2, "D3DFMT_YUY2", BLOCKS, 0},
1365 * {D3DFMT_UYVY, "D3DFMT_UYVY", BLOCKS, 0}, */
1366 {D3DFMT_DXT1, "D3DFMT_DXT1", BLOCKS, 0x00000000},
1367 /* Vendor-specific formats like ATI2N are a non-issue here since they're not
1368 * supported as offscreen plain surfaces and do not support D3DUSAGE_RENDERTARGET
1369 * when created as texture. */
1371 unsigned int i;
1372 D3DLOCKED_RECT locked_rect;
1373 DWORD *surface_data;
1374 static const RECT rect = {4, 4, 8, 8}, rect2 = {5, 5, 7, 7};
1376 window = create_window();
1377 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1378 ok(!!d3d, "Failed to create a D3D object.\n");
1379 if (!(device = create_device(d3d, window, window, TRUE)))
1381 skip("Failed to create a D3D device, skipping tests.\n");
1382 goto done;
1385 /* Test ColorFill on a the backbuffer (should pass) */
1386 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &surface);
1387 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1389 fill_color = 0x112233;
1390 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1391 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
1393 color = getPixelColor(device, 0, 0);
1394 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
1396 IDirect3DSurface9_Release(surface);
1398 /* Test ColorFill on a render target surface (should pass) */
1399 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8,
1400 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL );
1401 ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
1403 fill_color = 0x445566;
1404 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1405 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
1407 color = getPixelColorFromSurface(surface, 0, 0);
1408 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
1410 IDirect3DSurface9_Release(surface);
1412 /* Test ColorFill on an offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
1413 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1414 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surface, NULL);
1415 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
1417 fill_color = 0x778899;
1418 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1419 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
1421 color = getPixelColorFromSurface(surface, 0, 0);
1422 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
1424 IDirect3DSurface9_Release(surface);
1426 /* Try ColorFill on an offscreen surface in sysmem (should fail) */
1427 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1428 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1429 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
1431 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, 0);
1432 ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
1434 IDirect3DSurface9_Release(surface);
1436 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D16,
1437 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
1438 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr = %08x.\n", hr);
1440 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, 0);
1441 ok(hr == D3DERR_INVALIDCALL, "ColorFill on a depth stencil surface returned hr = %08x.\n", hr);
1443 IDirect3DSurface9_Release(surface);
1445 for (i = 0; i < sizeof(resource_types) / sizeof(resource_types[0]); i++)
1447 texture = NULL;
1448 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, resource_types[i].usage,
1449 D3DFMT_A8R8G8B8, resource_types[i].pool, &texture, NULL);
1450 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, i=%u.\n", hr, i);
1451 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1452 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x, i=%u.\n", hr, i);
1454 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1455 ok(hr == resource_types[i].hr, "Got unexpected hr %#x, expected %#x, i=%u.\n",
1456 hr, resource_types[i].hr, i);
1458 IDirect3DSurface9_Release(surface);
1459 IDirect3DTexture9_Release(texture);
1462 for (i = 0; i < sizeof(formats) / sizeof(formats[0]); i++)
1464 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
1465 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, formats[i].format) != D3D_OK)
1467 skip("Offscreenplain %s surfaces not supported, skipping colorfill test\n", formats[i].name);
1468 continue;
1471 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1472 formats[i].format, D3DPOOL_DEFAULT, &surface, NULL);
1473 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x, fmt=%s.\n", hr, formats[i].name);
1475 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, 0xdeadbeef);
1476 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x, fmt=%s.\n", hr, formats[i].name);
1478 hr = IDirect3DDevice9_ColorFill(device, surface, &rect, 0xdeadbeef);
1479 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x, fmt=%s.\n", hr, formats[i].name);
1481 if (SUCCEEDED(hr))
1483 hr = IDirect3DDevice9_ColorFill(device, surface, &rect2, 0xdeadbeef);
1484 if (formats[i].flags & BLOCKS)
1485 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, fmt=%s.\n", hr, formats[i].name);
1486 else
1487 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x, fmt=%s.\n", hr, formats[i].name);
1490 if (formats[i].flags & CHECK_FILL_VALUE)
1492 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, D3DLOCK_READONLY);
1493 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x, fmt=%s.\n", hr, formats[i].name);
1494 surface_data = locked_rect.pBits;
1495 fill_a = (surface_data[0] & 0xff000000) >> 24;
1496 expected_a = (formats[i].fill_value & 0xff000000) >> 24;
1497 /* Windows drivers disagree on how to promote the 8 bit per channel
1498 * input argument to 16 bit for D3DFMT_G16R16. */
1499 ok(color_match(surface_data[0], formats[i].fill_value, 2) &&
1500 abs((expected_a) - (fill_a)) < 3,
1501 "Expected clear value 0x%08x, got 0x%08x, fmt=%s.\n",
1502 formats[i].fill_value, surface_data[0], formats[i].name);
1503 hr = IDirect3DSurface9_UnlockRect(surface);
1504 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, fmt=%s.\n", hr, formats[i].name);
1507 IDirect3DSurface9_Release(surface);
1510 refcount = IDirect3DDevice9_Release(device);
1511 ok(!refcount, "Device has %u references left.\n", refcount);
1512 done:
1513 IDirect3D9_Release(d3d);
1514 DestroyWindow(window);
1518 * c7 mova ARGB mov ARGB
1519 * -2.4 -2 0x00ffff00 -3 0x00ff0000
1520 * -1.6 -2 0x00ffff00 -2 0x00ffff00
1521 * -0.4 0 0x0000ffff -1 0x0000ff00
1522 * 0.4 0 0x0000ffff 0 0x0000ffff
1523 * 1.6 2 0x00ff00ff 1 0x000000ff
1524 * 2.4 2 0x00ff00ff 2 0x00ff00ff
1526 static void test_mova(void)
1528 IDirect3DVertexDeclaration9 *vertex_declaration;
1529 IDirect3DVertexShader9 *mova_shader;
1530 IDirect3DVertexShader9 *mov_shader;
1531 IDirect3DDevice9 *device;
1532 unsigned int i, j;
1533 IDirect3D9 *d3d;
1534 ULONG refcount;
1535 D3DCAPS9 caps;
1536 HWND window;
1537 HRESULT hr;
1539 static const DWORD mova_test[] =
1541 0xfffe0200, /* vs_2_0 */
1542 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1543 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
1544 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
1545 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
1546 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
1547 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
1548 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
1549 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
1550 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
1551 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
1552 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1553 0x0000ffff /* END */
1555 static const DWORD mov_test[] =
1557 0xfffe0101, /* vs_1_1 */
1558 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1559 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
1560 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
1561 0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
1562 0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
1563 0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
1564 0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
1565 0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
1566 0x00000001, 0xb0010000, 0xa0000007, /* mov a0.x, c7.x */
1567 0x00000001, 0xd00f0000, 0xa0e42003, /* mov oD0, c[a0.x + 3] */
1568 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1569 0x0000ffff /* END */
1571 static const struct
1573 float in[4];
1574 DWORD out;
1576 test_data[2][6] =
1579 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
1580 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
1581 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
1582 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
1583 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
1584 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
1587 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
1588 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
1589 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
1590 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
1591 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
1592 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
1595 static const struct vec3 quad[] =
1597 {-1.0f, -1.0f, 0.0f},
1598 {-1.0f, 1.0f, 0.0f},
1599 { 1.0f, -1.0f, 0.0f},
1600 { 1.0f, 1.0f, 0.0f},
1602 static const D3DVERTEXELEMENT9 decl_elements[] =
1604 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1605 D3DDECL_END()
1608 window = create_window();
1609 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1610 ok(!!d3d, "Failed to create a D3D object.\n");
1611 if (!(device = create_device(d3d, window, window, TRUE)))
1613 skip("Failed to create a D3D device, skipping tests.\n");
1614 goto done;
1617 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1618 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1619 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
1621 skip("No vs_2_0 support, skipping tests.\n");
1622 IDirect3DDevice9_Release(device);
1623 goto done;
1626 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
1627 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1628 hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
1629 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1630 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1631 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1632 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1633 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1635 hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
1636 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1637 for (j = 0; j < sizeof(test_data) / sizeof(*test_data); ++j)
1639 for (i = 0; i < sizeof(*test_data) / sizeof(**test_data); ++i)
1641 DWORD color;
1643 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
1644 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
1646 hr = IDirect3DDevice9_BeginScene(device);
1647 ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
1649 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
1650 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1652 hr = IDirect3DDevice9_EndScene(device);
1653 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
1655 color = getPixelColor(device, 320, 240);
1656 ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
1657 test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
1659 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1660 ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
1662 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1663 ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
1665 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
1666 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1669 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1670 IDirect3DVertexShader9_Release(mova_shader);
1671 IDirect3DVertexShader9_Release(mov_shader);
1672 refcount = IDirect3DDevice9_Release(device);
1673 ok(!refcount, "Device has %u references left.\n", refcount);
1674 done:
1675 IDirect3D9_Release(d3d);
1676 DestroyWindow(window);
1679 static void fog_test(void)
1681 float start = 0.0f, end = 1.0f;
1682 IDirect3DDevice9 *device;
1683 IDirect3D9 *d3d;
1684 D3DCOLOR color;
1685 ULONG refcount;
1686 D3DCAPS9 caps;
1687 HWND window;
1688 HRESULT hr;
1689 int i;
1691 /* Gets full z based fog with linear fog, no fog with specular color. */
1692 static const struct
1694 float x, y, z;
1695 D3DCOLOR diffuse;
1696 D3DCOLOR specular;
1698 untransformed_1[] =
1700 {-1.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
1701 {-1.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
1702 { 0.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
1703 { 0.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
1705 /* Ok, I am too lazy to deal with transform matrices. */
1706 untransformed_2[] =
1708 {-1.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
1709 {-1.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
1710 { 0.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
1711 { 0.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
1713 untransformed_3[] =
1715 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1716 {-1.0f, 1.0f, 0.5f, 0xffff0000, 0xff000000},
1717 { 1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1718 { 1.0f, 1.0f, 0.5f, 0xffff0000, 0xff000000},
1720 far_quad1[] =
1722 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1723 {-1.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
1724 { 0.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
1725 { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1727 far_quad2[] =
1729 {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1730 {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
1731 { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
1732 { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1734 /* Untransformed ones. Give them a different diffuse color to make the
1735 * test look nicer. It also makes making sure that they are drawn
1736 * correctly easier. */
1737 static const struct
1739 float x, y, z, rhw;
1740 D3DCOLOR diffuse;
1741 D3DCOLOR specular;
1743 transformed_1[] =
1745 {320.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1746 {640.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1747 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1748 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1750 transformed_2[] =
1752 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1753 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1754 {640.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1755 {320.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1757 static const struct
1759 struct vec3 position;
1760 DWORD diffuse;
1762 rev_fog_quads[] =
1764 {{-1.0f, -1.0f, 0.1f}, 0x000000ff},
1765 {{-1.0f, 0.0f, 0.1f}, 0x000000ff},
1766 {{ 0.0f, 0.0f, 0.1f}, 0x000000ff},
1767 {{ 0.0f, -1.0f, 0.1f}, 0x000000ff},
1769 {{ 0.0f, -1.0f, 0.9f}, 0x000000ff},
1770 {{ 0.0f, 0.0f, 0.9f}, 0x000000ff},
1771 {{ 1.0f, 0.0f, 0.9f}, 0x000000ff},
1772 {{ 1.0f, -1.0f, 0.9f}, 0x000000ff},
1774 {{ 0.0f, 0.0f, 0.4f}, 0x000000ff},
1775 {{ 0.0f, 1.0f, 0.4f}, 0x000000ff},
1776 {{ 1.0f, 1.0f, 0.4f}, 0x000000ff},
1777 {{ 1.0f, 0.0f, 0.4f}, 0x000000ff},
1779 {{-1.0f, 0.0f, 0.7f}, 0x000000ff},
1780 {{-1.0f, 1.0f, 0.7f}, 0x000000ff},
1781 {{ 0.0f, 1.0f, 0.7f}, 0x000000ff},
1782 {{ 0.0f, 0.0f, 0.7f}, 0x000000ff},
1784 static const D3DMATRIX ident_mat =
1786 1.0f, 0.0f, 0.0f, 0.0f,
1787 0.0f, 1.0f, 0.0f, 0.0f,
1788 0.0f, 0.0f, 1.0f, 0.0f,
1789 0.0f, 0.0f, 0.0f, 1.0f
1790 }}};
1791 static const D3DMATRIX world_mat1 =
1793 1.0f, 0.0f, 0.0f, 0.0f,
1794 0.0f, 1.0f, 0.0f, 0.0f,
1795 0.0f, 0.0f, 1.0f, 0.0f,
1796 0.0f, 0.0f, -0.5f, 1.0f
1797 }}};
1798 static const D3DMATRIX world_mat2 =
1800 1.0f, 0.0f, 0.0f, 0.0f,
1801 0.0f, 1.0f, 0.0f, 0.0f,
1802 0.0f, 0.0f, 1.0f, 0.0f,
1803 0.0f, 0.0f, 1.0f, 1.0f
1804 }}};
1805 static const D3DMATRIX proj_mat =
1807 1.0f, 0.0f, 0.0f, 0.0f,
1808 0.0f, 1.0f, 0.0f, 0.0f,
1809 0.0f, 0.0f, 1.0f, 0.0f,
1810 0.0f, 0.0f, -1.0f, 1.0f
1811 }}};
1812 static const WORD Indices[] = {0, 1, 2, 2, 3, 0};
1813 static const WORD Indices2[] =
1815 0, 1, 2, 2, 3, 0,
1816 4, 5, 6, 6, 7, 4,
1817 8, 9, 10, 10, 11, 8,
1818 12, 13, 14, 14, 15, 12,
1821 window = create_window();
1822 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1823 ok(!!d3d, "Failed to create a D3D object.\n");
1824 if (!(device = create_device(d3d, window, window, TRUE)))
1826 skip("Failed to create a D3D device, skipping tests.\n");
1827 goto done;
1830 memset(&caps, 0, sizeof(caps));
1831 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1832 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
1833 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1834 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1836 /* Setup initial states: No lighting, fog on, fog color */
1837 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
1838 ok(SUCCEEDED(hr), "Failed to disable D3DRS_ZENABLE, hr %#x.\n", hr);
1839 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1840 ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
1841 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1842 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
1843 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xff00ff00 /* A nice green */);
1844 ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
1845 /* Some of the tests seem to depend on the projection matrix explicitly
1846 * being set to an identity matrix, even though that's the default.
1847 * (AMD Radeon HD 6310, Windows 7) */
1848 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
1849 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
1851 /* First test: Both table fog and vertex fog off */
1852 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1853 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
1854 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1855 ok(hr == D3D_OK, "Turning off vertex fog returned %08x\n", hr);
1857 /* Start = 0, end = 1. Should be default, but set them */
1858 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1859 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1860 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1861 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1863 hr = IDirect3DDevice9_BeginScene(device);
1864 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1866 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1867 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1869 /* Untransformed, vertex fog = NONE, table fog = NONE:
1870 * Read the fog weighting from the specular color. */
1871 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1872 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1873 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1875 /* That makes it use the Z value */
1876 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1877 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex mode, hr %#x.\n", hr);
1878 /* Untransformed, vertex fog != none (or table fog != none):
1879 * Use the Z value as input into the equation. */
1880 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1881 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1882 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1884 /* transformed verts */
1885 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1886 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1887 /* Transformed, vertex fog != NONE, pixel fog == NONE:
1888 * Use specular color alpha component. */
1889 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1890 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_1, sizeof(transformed_1[0]));
1891 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1893 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1894 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog table mode, hr %#x.\n", hr);
1895 /* Transformed, table fog != none, vertex anything:
1896 * Use Z value as input to the fog equation. */
1897 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1898 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_2, sizeof(transformed_2[0]));
1899 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1901 hr = IDirect3DDevice9_EndScene(device);
1902 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1904 color = getPixelColor(device, 160, 360);
1905 ok(color == 0x00ff0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1906 color = getPixelColor(device, 160, 120);
1907 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
1908 color = getPixelColor(device, 480, 120);
1909 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1910 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1912 color = getPixelColor(device, 480, 360);
1913 ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
1915 else
1917 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1918 * The settings above result in no fogging with vertex fog
1920 color = getPixelColor(device, 480, 120);
1921 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1922 trace("Info: Table fog not supported by this device\n");
1924 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1926 /* Now test the special case fogstart == fogend */
1927 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1928 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1930 hr = IDirect3DDevice9_BeginScene(device);
1931 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1933 start = 512;
1934 end = 512;
1935 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
1936 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#x.\n", hr);
1937 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
1938 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#x.\n", hr);
1940 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1941 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1942 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1943 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex mode, hr %#x.\n", hr);
1944 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1945 ok(SUCCEEDED(hr), "Failed to set D3DFOG_NONE fog table mode, hr %#x.\n", hr);
1947 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512.
1948 * Would result in a completely fog-free primitive because start > zcoord,
1949 * but because start == end, the primitive is fully covered by fog. The
1950 * same happens to the 2nd untransformed quad with z = 1.0. The third
1951 * transformed quad remains unfogged because the fogcoords are read from
1952 * the specular color and has fixed fogstart and fogend. */
1953 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1954 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1955 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1956 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1957 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1958 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1960 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1961 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1962 /* Transformed, vertex fog != NONE, pixel fog == NONE:
1963 * Use specular color alpha component. */
1964 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1965 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_1, sizeof(transformed_1[0]));
1966 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1968 hr = IDirect3DDevice9_EndScene(device);
1969 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1971 color = getPixelColor(device, 160, 360);
1972 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1973 color = getPixelColor(device, 160, 120);
1974 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1975 color = getPixelColor(device, 480, 120);
1976 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1977 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1979 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1980 * but without shaders it seems to work everywhere
1982 end = 0.2;
1983 start = 0.8;
1984 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1985 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1986 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1987 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1988 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1989 ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1991 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1992 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1993 * so skip this for now
1995 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1996 const char *mode = (i ? "table" : "vertex");
1997 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1998 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1999 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
2000 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2001 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
2002 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2003 hr = IDirect3DDevice9_BeginScene(device);
2004 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2005 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 16 /* NumVerts */,
2006 8 /* PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads, sizeof(rev_fog_quads[0]));
2007 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2008 hr = IDirect3DDevice9_EndScene(device);
2009 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2011 color = getPixelColor(device, 160, 360);
2012 ok(color_match(color, 0x0000ff00, 1),
2013 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
2015 color = getPixelColor(device, 160, 120);
2016 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
2017 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
2019 color = getPixelColor(device, 480, 120);
2020 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
2021 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
2023 color = getPixelColor(device, 480, 360);
2024 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
2026 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2028 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
2029 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
2030 break;
2034 if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
2036 /* A simple fog + non-identity world matrix test */
2037 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat1);
2038 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %#08x\n", hr);
2040 start = 0.0;
2041 end = 1.0;
2042 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
2043 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
2044 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
2045 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
2046 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
2047 ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
2048 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
2049 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
2051 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2052 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %#08x\n", hr);
2054 hr = IDirect3DDevice9_BeginScene(device);
2055 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2057 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
2058 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
2060 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2061 2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
2062 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2063 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2064 2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
2065 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2067 hr = IDirect3DDevice9_EndScene(device);
2068 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2070 color = getPixelColor(device, 160, 360);
2071 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 4),
2072 "Unfogged quad has color %08x\n", color);
2073 color = getPixelColor(device, 160, 120);
2074 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2075 "Fogged out quad has color %08x\n", color);
2077 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2079 /* Test fog behavior with an orthogonal (but non-identity) projection matrix */
2080 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat2);
2081 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
2082 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &proj_mat);
2083 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
2085 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2086 ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
2088 hr = IDirect3DDevice9_BeginScene(device);
2089 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2091 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
2092 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
2094 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2095 2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
2096 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2097 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2098 2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
2099 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2101 hr = IDirect3DDevice9_EndScene(device);
2102 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2104 color = getPixelColor(device, 160, 360);
2105 ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
2106 color = getPixelColor(device, 160, 120);
2107 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2108 "Fogged out quad has color %08x\n", color);
2110 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2112 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &ident_mat);
2113 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
2114 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
2115 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
2117 else
2119 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
2122 /* Test RANGEFOG vs FOGTABLEMODE */
2123 if ((caps.RasterCaps & (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE)) ==
2124 (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE))
2126 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2127 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
2128 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
2129 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
2131 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, TRUE);
2132 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
2134 /* z=0.5, x = +/- 1.0, y = +/- 1.0. In case of z fog the fog coordinate is
2135 * 0.5. With range fog it is sqrt(x*x + y*y + z*z) = 1.5 for all vertices.
2136 * Note that the fog coordinate is interpolated linearly across the vertices,
2137 * so the different eye distance at the screen center should not matter. */
2138 start = 0.75f;
2139 end = 0.75001f;
2140 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
2141 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
2142 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
2143 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
2145 /* Table fog: Range fog is not used */
2146 hr = IDirect3DDevice9_BeginScene(device);
2147 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2149 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
2150 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog table mode, hr %#x.\n", hr);
2151 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
2152 untransformed_3, sizeof(*untransformed_3));
2153 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2155 hr = IDirect3DDevice9_EndScene(device);
2156 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2158 color = getPixelColor(device, 10, 10);
2159 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2160 color = getPixelColor(device, 630, 10);
2161 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2162 color = getPixelColor(device, 10, 470);
2163 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2164 color = getPixelColor(device, 630, 470);
2165 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2167 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2168 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
2170 /* Vertex fog: Rangefog is used */
2171 hr = IDirect3DDevice9_BeginScene(device);
2172 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2174 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
2175 ok(SUCCEEDED(hr), "Failed to set D3DFOG_NONE fog table mode, hr %#x.\n", hr);
2176 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
2177 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex mode, hr %#x.\n", hr);
2178 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
2179 untransformed_3, sizeof(*untransformed_3));
2180 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2182 hr = IDirect3DDevice9_EndScene(device);
2183 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2185 color = getPixelColor(device, 10, 10);
2186 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2187 "Rangefog with vertex fog returned color 0x%08x\n", color);
2188 color = getPixelColor(device, 630, 10);
2189 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2190 "Rangefog with vertex fog returned color 0x%08x\n", color);
2191 color = getPixelColor(device, 10, 470);
2192 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2193 "Rangefog with vertex fog returned color 0x%08x\n", color);
2194 color = getPixelColor(device, 630, 470);
2195 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2196 "Rangefog with vertex fog returned color 0x%08x\n", color);
2198 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2199 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
2201 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, FALSE);
2202 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
2204 else
2206 skip("Range fog or table fog not supported, skipping range fog tests\n");
2209 refcount = IDirect3DDevice9_Release(device);
2210 ok(!refcount, "Device has %u references left.\n", refcount);
2211 done:
2212 IDirect3D9_Release(d3d);
2213 DestroyWindow(window);
2216 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
2217 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
2218 * regardless of the actual addressing mode set. The way this test works is
2219 * that we sample in one of the corners of the cubemap with filtering enabled,
2220 * and check the interpolated color. There are essentially two reasonable
2221 * things an implementation can do: Either pick one of the faces and
2222 * interpolate the edge texel with itself (i.e., clamp within the face), or
2223 * interpolate between the edge texels of the three involved faces. It should
2224 * never involve the border color or the other side (texcoord wrapping) of a
2225 * face in the interpolation. */
2226 static void test_cube_wrap(void)
2228 IDirect3DVertexDeclaration9 *vertex_declaration;
2229 IDirect3DSurface9 *face_surface, *surface;
2230 IDirect3DCubeTexture9 *texture;
2231 D3DLOCKED_RECT locked_rect;
2232 IDirect3DDevice9 *device;
2233 unsigned int x, y, face;
2234 IDirect3D9 *d3d;
2235 ULONG refcount;
2236 D3DCAPS9 caps;
2237 HWND window;
2238 HRESULT hr;
2240 static const float quad[][6] =
2242 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2243 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2244 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2245 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2247 static const D3DVERTEXELEMENT9 decl_elements[] =
2249 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2250 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2251 D3DDECL_END()
2253 static const struct
2255 D3DTEXTUREADDRESS mode;
2256 const char *name;
2258 address_modes[] =
2260 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
2261 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
2262 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
2263 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
2264 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
2267 window = create_window();
2268 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2269 ok(!!d3d, "Failed to create a D3D object.\n");
2270 if (!(device = create_device(d3d, window, window, TRUE)))
2272 skip("Failed to create a D3D device, skipping tests.\n");
2273 goto done;
2276 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2277 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2278 if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP))
2280 skip("No cube texture support, skipping tests.\n");
2281 IDirect3DDevice9_Release(device);
2282 goto done;
2285 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
2286 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
2287 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2288 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
2290 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
2291 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
2292 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
2294 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
2295 D3DPOOL_DEFAULT, &texture, NULL);
2296 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
2298 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
2299 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2301 for (y = 0; y < 128; ++y)
2303 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2304 for (x = 0; x < 64; ++x)
2306 *ptr++ = 0xff0000ff;
2308 for (x = 64; x < 128; ++x)
2310 *ptr++ = 0xffff0000;
2314 hr = IDirect3DSurface9_UnlockRect(surface);
2315 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2317 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
2318 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
2320 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
2321 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
2323 IDirect3DSurface9_Release(face_surface);
2325 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
2326 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2328 for (y = 0; y < 128; ++y)
2330 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2331 for (x = 0; x < 64; ++x)
2333 *ptr++ = 0xffff0000;
2335 for (x = 64; x < 128; ++x)
2337 *ptr++ = 0xff0000ff;
2341 hr = IDirect3DSurface9_UnlockRect(surface);
2342 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2344 /* Create cube faces */
2345 for (face = 1; face < 6; ++face)
2347 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
2348 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
2350 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
2351 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
2353 IDirect3DSurface9_Release(face_surface);
2356 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
2357 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2359 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
2360 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2361 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
2362 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2363 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
2364 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
2366 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2367 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2369 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
2371 DWORD color;
2373 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
2374 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
2375 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
2376 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
2378 hr = IDirect3DDevice9_BeginScene(device);
2379 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2381 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2382 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2384 hr = IDirect3DDevice9_EndScene(device);
2385 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2387 color = getPixelColor(device, 320, 240);
2388 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
2389 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
2390 color, address_modes[x].name);
2392 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2393 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2395 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
2396 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
2399 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2400 IDirect3DCubeTexture9_Release(texture);
2401 IDirect3DSurface9_Release(surface);
2402 refcount = IDirect3DDevice9_Release(device);
2403 ok(!refcount, "Device has %u references left.\n", refcount);
2404 done:
2405 IDirect3D9_Release(d3d);
2406 DestroyWindow(window);
2409 static void offscreen_test(void)
2411 IDirect3DSurface9 *backbuffer, *offscreen;
2412 IDirect3DTexture9 *offscreenTexture;
2413 IDirect3DDevice9 *device;
2414 IDirect3D9 *d3d;
2415 D3DCOLOR color;
2416 ULONG refcount;
2417 HWND window;
2418 HRESULT hr;
2420 static const float quad[][5] =
2422 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
2423 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
2424 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
2425 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
2428 window = create_window();
2429 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2430 ok(!!d3d, "Failed to create a D3D object.\n");
2431 if (!(device = create_device(d3d, window, window, TRUE)))
2433 skip("Failed to create a D3D device, skipping tests.\n");
2434 goto done;
2437 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
2438 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
2440 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2441 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
2442 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
2443 if (!offscreenTexture)
2445 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5.\n");
2446 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2447 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
2448 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
2449 if (!offscreenTexture)
2451 skip("Cannot create an offscreen render target.\n");
2452 IDirect3DDevice9_Release(device);
2453 goto done;
2457 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2458 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2460 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
2461 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
2463 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2464 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
2466 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
2467 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
2468 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2469 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
2470 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2471 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2472 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2473 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2474 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2475 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2477 hr = IDirect3DDevice9_BeginScene(device);
2478 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2480 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
2481 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2482 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 1.0f, 0);
2483 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2485 /* Draw without textures - Should result in a white quad. */
2486 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2487 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2489 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
2490 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2491 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)offscreenTexture);
2492 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2494 /* This time with the texture. */
2495 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2496 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2498 hr = IDirect3DDevice9_EndScene(device);
2499 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2501 /* Center quad - should be white */
2502 color = getPixelColor(device, 320, 240);
2503 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2504 /* Some quad in the cleared part of the texture */
2505 color = getPixelColor(device, 170, 240);
2506 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
2507 /* Part of the originally cleared back buffer */
2508 color = getPixelColor(device, 10, 10);
2509 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2510 color = getPixelColor(device, 10, 470);
2511 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2513 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2515 IDirect3DSurface9_Release(backbuffer);
2516 IDirect3DTexture9_Release(offscreenTexture);
2517 IDirect3DSurface9_Release(offscreen);
2518 refcount = IDirect3DDevice9_Release(device);
2519 ok(!refcount, "Device has %u references left.\n", refcount);
2520 done:
2521 IDirect3D9_Release(d3d);
2522 DestroyWindow(window);
2525 /* This test tests fog in combination with shaders.
2526 * What's tested: linear fog (vertex and table) with pixel shader
2527 * linear table fog with non foggy vertex shader
2528 * vertex fog with foggy vertex shader, non-linear
2529 * fog with shader, non-linear fog with foggy shader,
2530 * linear table fog with foggy shader */
2531 static void fog_with_shader_test(void)
2533 IDirect3DVertexShader9 *vertex_shader[4] = {NULL, NULL, NULL, NULL};
2534 IDirect3DPixelShader9 *pixel_shader[3] = {NULL, NULL, NULL};
2535 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
2536 IDirect3DDevice9 *device;
2537 unsigned int i, j;
2538 IDirect3D9 *d3d;
2539 ULONG refcount;
2540 D3DCAPS9 caps;
2541 DWORD color;
2542 HWND window;
2543 HRESULT hr;
2544 union
2546 float f;
2547 DWORD i;
2548 } start, end;
2550 /* basic vertex shader without fog computation ("non foggy") */
2551 static const DWORD vertex_shader_code1[] =
2553 0xfffe0101, /* vs_1_1 */
2554 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2555 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
2556 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2557 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
2558 0x0000ffff
2560 /* basic vertex shader with reversed fog computation ("foggy") */
2561 static const DWORD vertex_shader_code2[] =
2563 0xfffe0101, /* vs_1_1 */
2564 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2565 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
2566 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
2567 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2568 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
2569 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
2570 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
2571 0x0000ffff
2573 /* basic vertex shader with reversed fog computation ("foggy"), vs_2_0 */
2574 static const DWORD vertex_shader_code3[] =
2576 0xfffe0200, /* vs_2_0 */
2577 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2578 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
2579 0x05000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
2580 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2581 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
2582 0x03000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
2583 0x03000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
2584 0x0000ffff
2586 /* basic pixel shader */
2587 static const DWORD pixel_shader_code[] =
2589 0xffff0101, /* ps_1_1 */
2590 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
2591 0x0000ffff
2593 static const DWORD pixel_shader_code2[] =
2595 0xffff0200, /* ps_2_0 */
2596 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
2597 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
2598 0x0000ffff
2600 struct
2602 struct vec3 position;
2603 DWORD diffuse;
2605 quad[] =
2607 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
2608 {{-1.0f, 1.0f, 0.0f}, 0xffff0000},
2609 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
2610 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000},
2612 static const D3DVERTEXELEMENT9 decl_elements[] =
2614 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2615 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
2616 D3DDECL_END()
2618 /* This reference data was collected on a nVidia GeForce 7600GS driver
2619 * version 84.19 DirectX version 9.0c on Windows XP. */
2620 static const struct test_data_t
2622 int vshader;
2623 int pshader;
2624 D3DFOGMODE vfog;
2625 D3DFOGMODE tfog;
2626 unsigned int color[11];
2628 test_data[] =
2630 /* only pixel shader: */
2631 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
2632 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2633 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2634 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
2635 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2636 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2637 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
2638 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2639 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2640 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2641 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2642 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2643 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
2644 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2645 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2647 /* vertex shader */
2648 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
2649 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2650 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2651 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
2652 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2653 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2654 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
2655 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2656 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2658 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
2659 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2660 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2661 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
2662 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2663 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2665 /* vertex shader and pixel shader */
2666 /* The next 4 tests would read the fog coord output, but it isn't available.
2667 * The result is a fully fogged quad, no matter what the Z coord is. This is on
2668 * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
2669 * These tests should be disabled if some other hardware behaves differently
2671 {1, 1, D3DFOG_NONE, D3DFOG_NONE,
2672 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2673 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2674 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2675 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2676 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2677 {1, 1, D3DFOG_EXP, D3DFOG_NONE,
2678 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2679 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2680 {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
2681 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2682 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2684 /* These use the Z coordinate with linear table fog */
2685 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
2686 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2687 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2688 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
2689 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2690 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2691 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
2692 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2693 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2694 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
2695 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2696 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2698 /* Non-linear table fog without fog coord */
2699 {1, 1, D3DFOG_NONE, D3DFOG_EXP,
2700 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
2701 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
2702 {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
2703 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
2704 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
2706 /* These tests fail on older Nvidia drivers */
2707 /* foggy vertex shader */
2708 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
2709 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2710 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2711 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
2712 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2713 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2714 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
2715 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2716 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2717 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
2718 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2719 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2721 {3, 0, D3DFOG_NONE, D3DFOG_NONE,
2722 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2723 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2724 {3, 0, D3DFOG_EXP, D3DFOG_NONE,
2725 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2726 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2727 {3, 0, D3DFOG_EXP2, D3DFOG_NONE,
2728 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2729 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2730 {3, 0, D3DFOG_LINEAR, D3DFOG_NONE,
2731 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2732 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2734 /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
2735 * all using the fixed fog-coord linear fog
2737 /* vs_1_1 with ps_1_1 */
2738 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
2739 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2740 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2741 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
2742 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2743 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2744 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
2745 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2746 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2747 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2748 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2749 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2751 /* vs_2_0 with ps_1_1 */
2752 {3, 1, D3DFOG_NONE, D3DFOG_NONE,
2753 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2754 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2755 {3, 1, D3DFOG_EXP, D3DFOG_NONE,
2756 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2757 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2758 {3, 1, D3DFOG_EXP2, D3DFOG_NONE,
2759 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2760 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2761 {3, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2762 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2763 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2765 /* vs_1_1 with ps_2_0 */
2766 {2, 2, D3DFOG_NONE, D3DFOG_NONE,
2767 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2768 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2769 {2, 2, D3DFOG_EXP, D3DFOG_NONE,
2770 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2771 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2772 {2, 2, D3DFOG_EXP2, D3DFOG_NONE,
2773 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2774 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2775 {2, 2, D3DFOG_LINEAR, D3DFOG_NONE,
2776 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2777 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2779 /* vs_2_0 with ps_2_0 */
2780 {3, 2, D3DFOG_NONE, D3DFOG_NONE,
2781 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2782 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2783 {3, 2, D3DFOG_EXP, D3DFOG_NONE,
2784 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2785 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2786 {3, 2, D3DFOG_EXP2, D3DFOG_NONE,
2787 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2788 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2789 {3, 2, D3DFOG_LINEAR, D3DFOG_NONE,
2790 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2791 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2793 /* These use table fog. Here the shader-provided fog coordinate is
2794 * ignored and the z coordinate used instead
2796 {2, 1, D3DFOG_NONE, D3DFOG_EXP,
2797 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
2798 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
2799 {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
2800 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
2801 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
2802 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
2803 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2804 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2806 static const D3DMATRIX identity =
2808 1.0f, 0.0f, 0.0f, 0.0f,
2809 0.0f, 1.0f, 0.0f, 0.0f,
2810 0.0f, 0.0f, 1.0f, 0.0f,
2811 0.0f, 0.0f, 0.0f, 1.0f,
2812 }}};
2814 window = create_window();
2815 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2816 ok(!!d3d, "Failed to create a D3D object.\n");
2817 if (!(device = create_device(d3d, window, window, TRUE)))
2819 skip("Failed to create a D3D device, skipping tests.\n");
2820 goto done;
2823 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2824 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2825 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0) || caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
2827 skip("No shader model 2 support, skipping tests.\n");
2828 IDirect3DDevice9_Release(device);
2829 goto done;
2832 /* NOTE: Changing these values will not affect the tests with foggy vertex
2833 * shader, as the values are hardcoded in the shader. */
2834 start.f = 0.1f;
2835 end.f = 0.9f;
2837 /* Some of the tests seem to depend on the projection matrix explicitly
2838 * being set to an identity matrix, even though that's the default.
2839 * (AMD Radeon HD 6310, Windows 7) */
2840 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
2841 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
2843 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
2844 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2845 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
2846 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2847 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code3, &vertex_shader[3]);
2848 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2849 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
2850 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2851 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code2, &pixel_shader[2]);
2852 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2853 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
2854 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
2856 /* Setup initial states: No lighting, fog on, fog color */
2857 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2858 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
2859 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
2860 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
2861 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xff00ff00 /* A nice green */);
2862 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
2863 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2864 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2866 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
2867 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
2868 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
2869 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
2871 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
2872 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
2873 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
2874 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
2875 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
2877 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
2879 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
2880 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2881 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
2882 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2883 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
2884 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2885 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
2886 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2888 for(j=0; j < 11; j++)
2890 /* Don't use the whole zrange to prevent rounding errors */
2891 quad[0].position.z = 0.001f + (float)j / 10.02f;
2892 quad[1].position.z = 0.001f + (float)j / 10.02f;
2893 quad[2].position.z = 0.001f + (float)j / 10.02f;
2894 quad[3].position.z = 0.001f + (float)j / 10.02f;
2896 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff00ff, 1.0f, 0);
2897 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2899 hr = IDirect3DDevice9_BeginScene(device);
2900 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
2902 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2903 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2905 hr = IDirect3DDevice9_EndScene(device);
2906 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
2908 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
2909 color = getPixelColor(device, 128, 240);
2910 ok(color_match(color, test_data[i].color[j], 13),
2911 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
2912 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
2915 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2917 IDirect3DVertexShader9_Release(vertex_shader[1]);
2918 IDirect3DVertexShader9_Release(vertex_shader[2]);
2919 IDirect3DVertexShader9_Release(vertex_shader[3]);
2920 IDirect3DPixelShader9_Release(pixel_shader[1]);
2921 IDirect3DPixelShader9_Release(pixel_shader[2]);
2922 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2923 refcount = IDirect3DDevice9_Release(device);
2924 ok(!refcount, "Device has %u references left.\n", refcount);
2925 done:
2926 IDirect3D9_Release(d3d);
2927 DestroyWindow(window);
2930 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
2931 unsigned int i, x, y;
2932 HRESULT hr;
2933 IDirect3DTexture9 *texture[2] = {NULL, NULL};
2934 D3DLOCKED_RECT locked_rect;
2936 /* Generate the textures */
2937 for(i=0; i<2; i++)
2939 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
2940 D3DPOOL_MANAGED, &texture[i], NULL);
2941 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
2943 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
2944 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2945 for (y = 0; y < 128; ++y)
2947 if(i)
2948 { /* Set up black texture with 2x2 texel white spot in the middle */
2949 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2950 for (x = 0; x < 128; ++x)
2952 *ptr++ = D3DCOLOR_ARGB(0xff, x * 2, y * 2, 0);
2955 else
2956 { /* Set up a displacement map which points away from the center parallel to the closest axis.
2957 * (if multiplied with bumpenvmat)
2959 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2960 for (x = 0; x < 128; ++x)
2962 if(abs(x-64)>abs(y-64))
2964 if(x < 64)
2965 *ptr++ = 0xc000;
2966 else
2967 *ptr++ = 0x4000;
2969 else
2971 if(y < 64)
2972 *ptr++ = 0x0040;
2973 else
2974 *ptr++ = 0x00c0;
2979 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
2980 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2982 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
2983 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2985 /* Disable texture filtering */
2986 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2987 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2988 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2989 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2991 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2992 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
2993 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2994 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
2998 /* Test the behavior of the texbem instruction with normal 2D and projective
2999 * 2D textures. */
3000 static void texbem_test(void)
3002 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
3003 /* Use asymmetric matrix to test loading. */
3004 float bumpenvmat[4] = {0.0f, 0.5f, -0.5f, 0.0f};
3005 IDirect3DPixelShader9 *pixel_shader = NULL;
3006 IDirect3DTexture9 *texture1, *texture2;
3007 IDirect3DTexture9 *texture = NULL;
3008 D3DLOCKED_RECT locked_rect;
3009 IDirect3DDevice9 *device;
3010 IDirect3D9 *d3d;
3011 ULONG refcount;
3012 D3DCAPS9 caps;
3013 DWORD color;
3014 HWND window;
3015 HRESULT hr;
3016 int i;
3018 static const DWORD pixel_shader_code[] =
3020 0xffff0101, /* ps_1_1*/
3021 0x00000042, 0xb00f0000, /* tex t0*/
3022 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
3023 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
3024 0x0000ffff
3026 static const DWORD double_texbem_code[] =
3028 0xffff0103, /* ps_1_3 */
3029 0x00000042, 0xb00f0000, /* tex t0 */
3030 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
3031 0x00000042, 0xb00f0002, /* tex t2 */
3032 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
3033 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
3034 0x0000ffff /* end */
3036 static const float quad[][7] =
3038 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
3039 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
3040 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
3041 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
3043 static const float quad_proj[][9] =
3045 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
3046 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
3047 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
3048 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
3050 static const float double_quad[] =
3052 -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3053 -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3054 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3055 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3057 static const D3DVERTEXELEMENT9 decl_elements[][4] =
3060 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3061 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3062 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
3063 D3DDECL_END()
3066 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3067 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3068 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
3069 D3DDECL_END()
3073 window = create_window();
3074 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3075 ok(!!d3d, "Failed to create a D3D object.\n");
3076 if (!(device = create_device(d3d, window, window, TRUE)))
3078 skip("Failed to create a D3D device, skipping tests.\n");
3079 goto done;
3082 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3083 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3084 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
3086 skip("No ps_1_1 support, skipping tests.\n");
3087 IDirect3DDevice9_Release(device);
3088 goto done;
3091 generate_bumpmap_textures(device);
3093 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
3094 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
3095 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
3096 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
3097 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
3099 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
3100 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
3102 for(i=0; i<2; i++)
3104 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
3105 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
3107 if(i)
3109 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
3110 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
3113 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
3114 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
3115 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
3116 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
3118 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
3119 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
3120 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
3121 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3123 hr = IDirect3DDevice9_BeginScene(device);
3124 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
3126 if(!i)
3127 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
3128 else
3129 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
3130 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
3132 hr = IDirect3DDevice9_EndScene(device);
3133 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
3135 /* The Window 8 testbot (WARP) seems to use the transposed
3136 * D3DTSS_BUMPENVMAT matrix. */
3137 color = getPixelColor(device, 160, 240);
3138 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00007e00, 4)),
3139 "Got unexpected color 0x%08x.\n", color);
3140 color = getPixelColor(device, 480, 240);
3141 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00fe7e00, 4)),
3142 "Got unexpected color 0x%08x.\n", color);
3143 color = getPixelColor(device, 320, 120);
3144 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x0080fe00, 4)),
3145 "Got unexpected color 0x%08x.\n", color);
3146 color = getPixelColor(device, 320, 360);
3147 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00800000, 4)),
3148 "Got unexpected color 0x%08x.\n", color);
3150 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3151 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3153 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3154 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3155 IDirect3DPixelShader9_Release(pixel_shader);
3157 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3158 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
3159 IDirect3DVertexDeclaration9_Release(vertex_declaration);
3162 /* clean up */
3163 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
3164 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
3166 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3167 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
3169 for(i=0; i<2; i++)
3171 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
3172 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
3173 IDirect3DTexture9_Release(texture); /* For the GetTexture */
3174 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
3175 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
3176 IDirect3DTexture9_Release(texture);
3179 /* Test double texbem */
3180 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
3181 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
3182 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
3183 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
3184 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
3185 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
3186 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
3187 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
3189 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
3190 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3191 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
3192 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
3194 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3195 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3197 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
3198 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3199 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
3200 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
3201 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
3202 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3205 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
3206 #define tex 0x00ff0000
3207 #define tex1 0x0000ff00
3208 #define origin 0x000000ff
3209 static const DWORD pixel_data[] = {
3210 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3211 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3212 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3213 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3214 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
3215 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3216 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3217 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3219 #undef tex1
3220 #undef tex2
3221 #undef origin
3223 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
3224 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3225 for(i = 0; i < 8; i++) {
3226 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
3228 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
3229 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3232 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3233 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3234 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
3235 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3236 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
3237 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3238 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
3239 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3240 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
3241 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
3242 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
3243 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
3245 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
3246 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
3247 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
3248 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3249 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
3250 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3251 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
3252 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3253 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
3254 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3256 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
3257 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
3258 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
3259 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3260 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
3261 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3262 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
3263 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3264 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
3265 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3267 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3268 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3269 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3270 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3271 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3272 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3273 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3274 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3275 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3276 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3277 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3278 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3279 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3280 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3281 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3282 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3284 hr = IDirect3DDevice9_BeginScene(device);
3285 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3286 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
3287 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
3288 hr = IDirect3DDevice9_EndScene(device);
3289 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3290 /* The Window 8 testbot (WARP) seems to use the transposed
3291 * D3DTSS_BUMPENVMAT matrix. */
3292 color = getPixelColor(device, 320, 240);
3293 ok(color_match(color, 0x00ffff00, 1) || broken(color_match(color, 0x0000ffff, 1)),
3294 "Got unexpected color 0x%08x.\n", color);
3296 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3297 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3299 IDirect3DPixelShader9_Release(pixel_shader);
3300 IDirect3DTexture9_Release(texture);
3301 IDirect3DTexture9_Release(texture1);
3302 IDirect3DTexture9_Release(texture2);
3303 refcount = IDirect3DDevice9_Release(device);
3304 ok(!refcount, "Device has %u references left.\n", refcount);
3305 done:
3306 IDirect3D9_Release(d3d);
3307 DestroyWindow(window);
3310 static void z_range_test(void)
3312 IDirect3DVertexShader9 *shader;
3313 IDirect3DDevice9 *device;
3314 IDirect3D9 *d3d;
3315 ULONG refcount;
3316 D3DCAPS9 caps;
3317 DWORD color;
3318 HWND window;
3319 HRESULT hr;
3321 static const struct
3323 struct vec3 position;
3324 DWORD diffuse;
3326 quad[] =
3328 {{-1.0f, 0.0f, 1.1f}, 0xffff0000},
3329 {{-1.0f, 1.0f, 1.1f}, 0xffff0000},
3330 {{ 1.0f, 0.0f, -1.1f}, 0xffff0000},
3331 {{ 1.0f, 1.0f, -1.1f}, 0xffff0000},
3333 quad2[] =
3335 {{-1.0f, 0.0f, 1.1f}, 0xff0000ff},
3336 {{-1.0f, 1.0f, 1.1f}, 0xff0000ff},
3337 {{ 1.0f, 0.0f, -1.1f}, 0xff0000ff},
3338 {{ 1.0f, 1.0f, -1.1f}, 0xff0000ff},
3340 static const struct
3342 struct vec4 position;
3343 DWORD diffuse;
3345 quad3[] =
3347 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xffffff00},
3348 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xffffff00},
3349 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xffffff00},
3350 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xffffff00},
3352 quad4[] =
3354 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xff00ff00},
3355 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xff00ff00},
3356 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xff00ff00},
3357 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xff00ff00},
3359 static const DWORD shader_code[] =
3361 0xfffe0101, /* vs_1_1 */
3362 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
3363 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
3364 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
3365 0x0000ffff /* end */
3367 static const float color_const_1[] = {1.0f, 0.0f, 0.0f, 1.0f};
3368 static const float color_const_2[] = {0.0f, 0.0f, 1.0f, 1.0f};
3370 window = create_window();
3371 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3372 ok(!!d3d, "Failed to create a D3D object.\n");
3373 if (!(device = create_device(d3d, window, window, TRUE)))
3375 skip("Failed to create a D3D device, skipping tests.\n");
3376 goto done;
3379 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3380 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3382 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
3383 * then call Present. Then clear the color buffer to make sure it has some defined content
3384 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
3385 * by the depth value. */
3386 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75f, 0);
3387 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3388 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3389 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
3390 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
3391 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3393 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3394 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
3395 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
3396 ok(SUCCEEDED(hr), "Failed to enable clipping, hr %#x.\n", hr);
3397 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3398 ok(SUCCEEDED(hr), "Failed to enable z test, hr %#x.\n", hr);
3399 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3400 ok(SUCCEEDED(hr), "Failed to disable z writes, hr %#x.\n", hr);
3401 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3402 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3403 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3404 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
3406 hr = IDirect3DDevice9_BeginScene(device);
3407 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3409 /* Test the untransformed vertex path */
3410 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
3411 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3412 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
3413 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3414 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
3415 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3417 /* Test the transformed vertex path */
3418 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
3419 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
3421 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
3422 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3423 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3424 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3425 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
3426 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3428 hr = IDirect3DDevice9_EndScene(device);
3429 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3431 /* Do not test the exact corner pixels, but go pretty close to them */
3433 /* Clipped because z > 1.0 */
3434 color = getPixelColor(device, 28, 238);
3435 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3436 color = getPixelColor(device, 28, 241);
3437 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
3438 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3439 else
3440 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
3442 /* Not clipped, > z buffer clear value(0.75).
3444 * On the r500 driver on Windows D3DCMP_GREATER and D3DCMP_GREATEREQUAL are broken for depth
3445 * values > 0.5. The range appears to be distorted, apparently an incoming value of ~0.875 is
3446 * equal to a stored depth buffer value of 0.5. */
3447 color = getPixelColor(device, 31, 238);
3448 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3449 color = getPixelColor(device, 31, 241);
3450 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
3451 color = getPixelColor(device, 100, 238);
3452 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
3453 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3454 color = getPixelColor(device, 100, 241);
3455 ok(color_match(color, 0x00ffff00, 0) || broken(color_match(color, 0x00ffffff, 0)),
3456 "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
3458 /* Not clipped, < z buffer clear value */
3459 color = getPixelColor(device, 104, 238);
3460 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3461 color = getPixelColor(device, 104, 241);
3462 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
3463 color = getPixelColor(device, 318, 238);
3464 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3465 color = getPixelColor(device, 318, 241);
3466 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
3468 /* Clipped because z < 0.0 */
3469 color = getPixelColor(device, 321, 238);
3470 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3471 color = getPixelColor(device, 321, 241);
3472 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
3473 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3474 else
3475 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3477 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3478 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
3480 /* Test the shader path */
3481 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
3483 skip("Vertex shaders not supported, skipping tests.\n");
3484 IDirect3DDevice9_Release(device);
3485 goto done;
3487 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
3488 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
3490 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
3491 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3493 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3494 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
3495 hr = IDirect3DDevice9_SetVertexShader(device, shader);
3496 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
3498 hr = IDirect3DDevice9_BeginScene(device);
3499 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3501 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, color_const_1, 1);
3502 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
3503 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
3504 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3506 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
3507 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3508 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, color_const_2, 1);
3509 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
3510 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
3511 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3513 hr = IDirect3DDevice9_EndScene(device);
3514 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3516 IDirect3DVertexShader9_Release(shader);
3518 /* Z < 1.0 */
3519 color = getPixelColor(device, 28, 238);
3520 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3522 /* 1.0 < z < 0.75 */
3523 color = getPixelColor(device, 31, 238);
3524 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3525 color = getPixelColor(device, 100, 238);
3526 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
3527 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3529 /* 0.75 < z < 0.0 */
3530 color = getPixelColor(device, 104, 238);
3531 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3532 color = getPixelColor(device, 318, 238);
3533 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3535 /* 0.0 < z */
3536 color = getPixelColor(device, 321, 238);
3537 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3539 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3540 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
3542 refcount = IDirect3DDevice9_Release(device);
3543 ok(!refcount, "Device has %u references left.\n", refcount);
3544 done:
3545 IDirect3D9_Release(d3d);
3546 DestroyWindow(window);
3549 static void fill_surface(IDirect3DSurface9 *surface, DWORD color, DWORD flags)
3551 D3DSURFACE_DESC desc;
3552 D3DLOCKED_RECT l;
3553 HRESULT hr;
3554 unsigned int x, y;
3555 DWORD *mem;
3557 memset(&desc, 0, sizeof(desc));
3558 memset(&l, 0, sizeof(l));
3559 hr = IDirect3DSurface9_GetDesc(surface, &desc);
3560 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
3561 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, flags);
3562 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
3563 if(FAILED(hr)) return;
3565 for(y = 0; y < desc.Height; y++)
3567 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
3568 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
3570 mem[x] = color;
3573 hr = IDirect3DSurface9_UnlockRect(surface);
3574 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
3577 static void stretchrect_test(void)
3579 IDirect3DSurface9 *surf_tex_rt32, *surf_tex_rt64, *surf_tex_rt_dest64, *surf_tex_rt_dest640_480;
3580 IDirect3DSurface9 *surf_offscreen32, *surf_offscreen64, *surf_offscreen_dest64;
3581 IDirect3DTexture9 *tex_rt32, *tex_rt64, *tex_rt_dest64, *tex_rt_dest640_480;
3582 IDirect3DSurface9 *surf_tex32, *surf_tex64, *surf_tex_dest64;
3583 IDirect3DSurface9 *surf_rt32, *surf_rt64, *surf_rt_dest64;
3584 IDirect3DTexture9 *tex32, *tex64, *tex_dest64;
3585 IDirect3DSurface9 *surf_temp32, *surf_temp64;
3586 IDirect3DSurface9 *backbuffer;
3587 IDirect3DDevice9 *device;
3588 IDirect3D9 *d3d;
3589 D3DCOLOR color;
3590 ULONG refcount;
3591 HWND window;
3592 HRESULT hr;
3594 static const RECT src_rect = {0, 0, 640, 480};
3595 static const RECT src_rect_flipy = {0, 480, 640, 0};
3596 static const RECT dst_rect = {0, 0, 640, 480};
3597 static const RECT dst_rect_flipy = {0, 480, 640, 0};
3598 static const RECT src_rect64 = {0, 0, 64, 64};
3599 static const RECT src_rect64_flipy = {0, 64, 64, 0};
3600 static const RECT dst_rect64 = {0, 0, 64, 64};
3601 static const RECT dst_rect64_flipy = {0, 64, 64, 0};
3603 window = create_window();
3604 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3605 ok(!!d3d, "Failed to create a D3D object.\n");
3606 if (!(device = create_device(d3d, window, window, TRUE)))
3608 skip("Failed to create a D3D device, skipping tests.\n");
3609 goto done;
3612 /* Create our temporary surfaces in system memory. */
3613 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
3614 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
3615 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3616 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
3617 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
3618 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3620 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT. */
3621 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
3622 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
3623 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3624 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
3625 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
3626 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3627 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
3628 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
3629 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3631 /* Create render target surfaces. */
3632 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32,
3633 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
3634 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
3635 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64,
3636 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
3637 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
3638 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64,
3639 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
3640 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
3641 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
3642 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
3644 /* Create render target textures. */
3645 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET,
3646 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
3647 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3648 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET,
3649 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
3650 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3651 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET,
3652 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
3653 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3654 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET,
3655 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
3656 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3657 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
3658 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3659 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
3660 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3661 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
3662 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3663 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
3664 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3666 /* Create regular textures in D3DPOOL_DEFAULT. */
3667 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
3668 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3669 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
3670 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3671 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
3672 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3673 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
3674 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3675 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
3676 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3677 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
3678 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3680 /**********************************************************************
3681 * Tests for when the source parameter is an offscreen plain surface. *
3682 **********************************************************************/
3684 /* Fill the offscreen 64x64 surface with green. */
3685 fill_surface(surf_offscreen64, 0xff00ff00, 0);
3687 /* offscreenplain ==> offscreenplain, same size. */
3688 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, D3DTEXF_NONE);
3689 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3690 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
3691 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
3692 /* Blit without scaling. */
3693 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3694 surf_offscreen_dest64, &dst_rect64, D3DTEXF_NONE);
3695 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3696 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3697 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy,
3698 surf_offscreen_dest64, &dst_rect64, D3DTEXF_NONE);
3699 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3700 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3701 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3702 surf_offscreen_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3703 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3705 /* offscreenplain ==> rendertarget texture, same size. */
3706 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3707 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3708 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3709 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3710 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3711 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3712 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
3713 /* Blit without scaling. */
3714 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3715 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3716 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3717 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3718 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy,
3719 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3720 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3721 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3722 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3723 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3724 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3726 /* offscreenplain ==> rendertarget surface, same size. */
3727 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3728 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3729 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3730 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
3731 /* Blit without scaling. */
3732 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3733 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3734 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3735 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3736 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy,
3737 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3738 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3739 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3740 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3741 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3742 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3744 /* offscreenplain ==> texture, same size (should fail). */
3745 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3746 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3748 /* Fill the smaller offscreen surface with red. */
3749 fill_surface(surf_offscreen32, 0xffff0000, 0);
3751 /* offscreenplain ==> offscreenplain, scaling (should fail). */
3752 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3753 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3755 /* offscreenplain ==> rendertarget texture, scaling. */
3756 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3757 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3758 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3759 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3760 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3761 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3762 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3764 /* offscreenplain ==> rendertarget surface, scaling. */
3765 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3766 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3767 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3768 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3770 /* offscreenplain ==> texture, scaling (should fail). */
3771 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3772 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3774 /*************************************************************
3775 * Tests for when the source parameter is a regular texture. *
3776 *************************************************************/
3778 /* Fill the surface of the regular texture with blue. */
3779 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT. */
3780 fill_surface(surf_temp64, 0xff0000ff, 0);
3781 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
3782 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3784 /* texture ==> offscreenplain, same size. */
3785 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3786 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3788 /* texture ==> rendertarget texture, same size. */
3789 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3790 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3791 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3792 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3793 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3794 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3795 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
3796 /* Blit without scaling. */
3797 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3798 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3799 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3800 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3801 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy,
3802 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3803 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3804 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3805 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3806 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3807 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3809 /* texture ==> rendertarget surface, same size. */
3810 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3811 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3812 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3813 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
3814 /* Blit without scaling. */
3815 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3816 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3817 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3818 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3819 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy,
3820 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3821 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3822 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3823 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3824 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3825 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3827 /* texture ==> texture, same size (should fail). */
3828 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3829 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3831 /* Fill the surface of the smaller regular texture with red. */
3832 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT. */
3833 fill_surface(surf_temp32, 0xffff0000, 0);
3834 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
3835 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3837 /* texture ==> offscreenplain, scaling (should fail). */
3838 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3839 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3841 /* texture ==> rendertarget texture, scaling. */
3842 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3843 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3844 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3845 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3846 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3847 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3848 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3850 /* texture ==> rendertarget surface, scaling. */
3851 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3852 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3853 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3854 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3856 /* texture ==> texture, scaling (should fail). */
3857 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3858 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3860 /******************************************************************
3861 * Tests for when the source parameter is a rendertarget texture. *
3862 ******************************************************************/
3864 /* Fill the surface of the rendertarget texture with white. */
3865 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT. */
3866 fill_surface(surf_temp64, 0xffffffff, 0);
3867 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
3868 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3870 /* rendertarget texture ==> offscreenplain, same size. */
3871 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3872 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3874 /* rendertarget texture ==> rendertarget texture, same size. */
3875 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3876 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3877 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3878 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3879 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3880 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3881 ok(color == 0xffffffff, "Got unexpected color 0x%08x.\n", color);
3882 /* Blit without scaling. */
3883 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3884 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3885 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3886 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3887 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy,
3888 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3889 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3890 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3891 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3892 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3893 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3895 /* rendertarget texture ==> rendertarget surface, same size. */
3896 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3897 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3898 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3899 ok(color == 0xffffffff, "Got unexpected color 0x%08x.\n", color);
3900 /* Blit without scaling. */
3901 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3902 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3903 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3904 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3905 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy,
3906 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3907 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3908 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3909 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3910 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3911 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3913 /* rendertarget texture ==> texture, same size (should fail). */
3914 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3915 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3917 /* Fill the surface of the smaller rendertarget texture with red. */
3918 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT. */
3919 fill_surface(surf_temp32, 0xffff0000, 0);
3920 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
3921 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3923 /* rendertarget texture ==> offscreenplain, scaling (should fail). */
3924 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3925 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3927 /* rendertarget texture ==> rendertarget texture, scaling. */
3928 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3929 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3930 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3931 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3932 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3933 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3934 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3936 /* rendertarget texture ==> rendertarget surface, scaling. */
3937 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3938 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3939 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3940 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3942 /* rendertarget texture ==> texture, scaling (should fail). */
3943 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3944 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3946 /******************************************************************
3947 * Tests for when the source parameter is a rendertarget surface. *
3948 ******************************************************************/
3950 /* Fill the surface of the rendertarget surface with black. */
3951 fill_surface(surf_rt64, 0xff000000, 0);
3953 /* rendertarget texture ==> offscreenplain, same size. */
3954 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3955 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3957 /* rendertarget surface ==> rendertarget texture, same size. */
3958 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3959 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3960 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3961 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3962 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3963 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3964 ok(color == 0xff000000, "Got unexpected color 0x%08x.\n", color);
3965 /* Blit without scaling. */
3966 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3967 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3968 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3969 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3970 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy,
3971 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3972 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3973 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3974 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3975 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3976 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3978 /* rendertarget surface ==> rendertarget surface, same size. */
3979 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3980 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3981 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3982 ok(color == 0xff000000, "Got unexpected color 0x%08x.\n", color);
3983 /* Blit without scaling. */
3984 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3985 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3986 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3987 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3988 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy,
3989 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3990 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3991 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3992 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3993 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3994 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3996 /* rendertarget surface ==> texture, same size (should fail). */
3997 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3998 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4000 /* Fill the surface of the smaller rendertarget texture with red. */
4001 fill_surface(surf_rt32, 0xffff0000, 0);
4003 /* rendertarget surface ==> offscreenplain, scaling (should fail). */
4004 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
4005 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4007 /* rendertarget surface ==> rendertarget texture, scaling. */
4008 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
4009 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4010 /* We can't lock rendertarget textures, so copy to our temp surface first. */
4011 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
4012 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
4013 color = getPixelColorFromSurface(surf_temp64, 48, 48);
4014 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
4016 /* rendertarget surface ==> rendertarget surface, scaling. */
4017 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
4018 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4019 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
4020 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
4022 /* rendertarget surface ==> texture, scaling (should fail). */
4023 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
4024 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4026 /* backbuffer ==> surface tests (no scaling). */
4027 /* Blit with NULL rectangles. */
4028 hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, D3DTEXF_NONE);
4029 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4030 /* Blit without scaling. */
4031 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect,
4032 surf_tex_rt_dest640_480, &dst_rect, D3DTEXF_NONE);
4033 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4034 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
4035 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy,
4036 surf_tex_rt_dest640_480, &dst_rect, D3DTEXF_NONE);
4037 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4038 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
4039 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect,
4040 surf_tex_rt_dest640_480, &dst_rect_flipy, D3DTEXF_NONE);
4041 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4043 /* TODO: Test format conversions. */
4045 IDirect3DSurface9_Release(backbuffer);
4046 IDirect3DSurface9_Release(surf_rt32);
4047 IDirect3DSurface9_Release(surf_rt64);
4048 IDirect3DSurface9_Release(surf_rt_dest64);
4049 IDirect3DSurface9_Release(surf_temp32);
4050 IDirect3DSurface9_Release(surf_temp64);
4051 IDirect3DSurface9_Release(surf_offscreen32);
4052 IDirect3DSurface9_Release(surf_offscreen64);
4053 IDirect3DSurface9_Release(surf_offscreen_dest64);
4054 IDirect3DSurface9_Release(surf_tex_rt32);
4055 IDirect3DTexture9_Release(tex_rt32);
4056 IDirect3DSurface9_Release(surf_tex_rt64);
4057 IDirect3DTexture9_Release(tex_rt64);
4058 IDirect3DSurface9_Release(surf_tex_rt_dest64);
4059 IDirect3DTexture9_Release(tex_rt_dest64);
4060 IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
4061 IDirect3DTexture9_Release(tex_rt_dest640_480);
4062 IDirect3DSurface9_Release(surf_tex32);
4063 IDirect3DTexture9_Release(tex32);
4064 IDirect3DSurface9_Release(surf_tex64);
4065 IDirect3DTexture9_Release(tex64);
4066 IDirect3DSurface9_Release(surf_tex_dest64);
4067 IDirect3DTexture9_Release(tex_dest64);
4068 refcount = IDirect3DDevice9_Release(device);
4069 ok(!refcount, "Device has %u references left.\n", refcount);
4070 done:
4071 IDirect3D9_Release(d3d);
4072 DestroyWindow(window);
4075 static void maxmip_test(void)
4077 IDirect3DTexture9 *texture;
4078 IDirect3DSurface9 *surface;
4079 IDirect3DDevice9 *device;
4080 IDirect3D9 *d3d;
4081 D3DCOLOR color;
4082 ULONG refcount;
4083 D3DCAPS9 caps;
4084 HWND window;
4085 HRESULT hr;
4086 DWORD ret;
4088 static const struct
4090 struct
4092 float x, y, z;
4093 float s, t;
4095 v[4];
4097 quads[] =
4100 {-1.0, -1.0, 0.0, 0.0, 0.0},
4101 {-1.0, 0.0, 0.0, 0.0, 1.0},
4102 { 0.0, -1.0, 0.0, 1.0, 0.0},
4103 { 0.0, 0.0, 0.0, 1.0, 1.0},
4106 { 0.0, -1.0, 0.0, 0.0, 0.0},
4107 { 0.0, 0.0, 0.0, 0.0, 1.0},
4108 { 1.0, -1.0, 0.0, 1.0, 0.0},
4109 { 1.0, 0.0, 0.0, 1.0, 1.0},
4112 { 0.0, 0.0, 0.0, 0.0, 0.0},
4113 { 0.0, 1.0, 0.0, 0.0, 1.0},
4114 { 1.0, 0.0, 0.0, 1.0, 0.0},
4115 { 1.0, 1.0, 0.0, 1.0, 1.0},
4118 {-1.0, 0.0, 0.0, 0.0, 0.0},
4119 {-1.0, 1.0, 0.0, 0.0, 1.0},
4120 { 0.0, 0.0, 0.0, 1.0, 0.0},
4121 { 0.0, 1.0, 0.0, 1.0, 1.0},
4125 window = create_window();
4126 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4127 ok(!!d3d, "Failed to create a D3D object.\n");
4128 if (!(device = create_device(d3d, window, window, TRUE)))
4130 skip("Failed to create a D3D device, skipping tests.\n");
4131 goto done;
4134 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4135 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4136 if (!(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP))
4138 skip("No mipmap support, skipping tests.\n");
4139 IDirect3DDevice9_Release(device);
4140 goto done;
4143 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0,
4144 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
4145 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
4147 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4148 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
4149 fill_surface(surface, 0xffff0000, 0);
4150 IDirect3DSurface9_Release(surface);
4151 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
4152 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
4153 fill_surface(surface, 0xff00ff00, 0);
4154 IDirect3DSurface9_Release(surface);
4155 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
4156 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
4157 fill_surface(surface, 0xff0000ff, 0);
4158 IDirect3DSurface9_Release(surface);
4160 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4161 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4162 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4163 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4165 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4166 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4167 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4168 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4170 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
4171 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4173 hr = IDirect3DDevice9_BeginScene(device);
4174 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4176 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
4177 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4178 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
4179 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4181 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
4182 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4183 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
4184 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4186 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4187 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4188 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
4189 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4191 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
4192 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4193 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
4194 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4196 hr = IDirect3DDevice9_EndScene(device);
4197 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4199 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
4200 color = getPixelColor(device, 160, 360);
4201 ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
4202 color = getPixelColor(device, 480, 360);
4203 ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
4204 color = getPixelColor(device, 480, 120);
4205 ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
4206 color = getPixelColor(device, 160, 120);
4207 ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
4208 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4209 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4211 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4212 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4214 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
4215 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4217 hr = IDirect3DDevice9_BeginScene(device);
4218 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4220 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
4221 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4222 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
4223 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4225 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
4226 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4227 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
4228 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4230 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4231 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4232 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
4233 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4235 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
4236 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4237 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
4238 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4240 hr = IDirect3DDevice9_EndScene(device);
4241 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4243 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
4244 * level 3 (> levels in texture) samples from the highest level in the
4245 * texture (level 2). */
4246 color = getPixelColor(device, 160, 360);
4247 ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
4248 color = getPixelColor(device, 480, 360);
4249 ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
4250 color = getPixelColor(device, 480, 120);
4251 ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
4252 color = getPixelColor(device, 160, 120);
4253 ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
4254 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4255 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4257 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
4258 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4260 hr = IDirect3DDevice9_BeginScene(device);
4261 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4263 /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
4264 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4265 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4266 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
4267 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4268 ret = IDirect3DTexture9_SetLOD(texture, 1);
4269 ok(ret == 0, "Got unexpected LOD %u.\n", ret);
4270 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
4271 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4273 /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
4274 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4275 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4276 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
4277 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4278 ret = IDirect3DTexture9_SetLOD(texture, 2);
4279 ok(ret == 1, "Got unexpected LOD %u.\n", ret);
4280 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
4281 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4283 /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
4284 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4285 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4286 ret = IDirect3DTexture9_SetLOD(texture, 1);
4287 ok(ret == 2, "Got unexpected LOD %u.\n", ret);
4288 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
4289 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4291 /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
4292 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4293 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4294 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4295 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4296 ret = IDirect3DTexture9_SetLOD(texture, 1);
4297 ok(ret == 1, "Got unexpected LOD %u.\n", ret);
4298 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
4299 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4301 hr = IDirect3DDevice9_EndScene(device);
4302 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4304 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
4305 * level 3 (> levels in texture) samples from the highest level in the
4306 * texture (level 2). */
4307 color = getPixelColor(device, 160, 360);
4308 ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
4309 color = getPixelColor(device, 480, 360);
4310 ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
4311 color = getPixelColor(device, 480, 120);
4312 ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
4313 color = getPixelColor(device, 160, 120);
4314 ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
4316 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4317 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4319 IDirect3DTexture9_Release(texture);
4320 refcount = IDirect3DDevice9_Release(device);
4321 ok(!refcount, "Device has %u references left.\n", refcount);
4322 done:
4323 IDirect3D9_Release(d3d);
4324 DestroyWindow(window);
4327 static void release_buffer_test(void)
4329 IDirect3DVertexBuffer9 *vb;
4330 IDirect3DIndexBuffer9 *ib;
4331 IDirect3DDevice9 *device;
4332 IDirect3D9 *d3d;
4333 D3DCOLOR color;
4334 ULONG refcount;
4335 HWND window;
4336 HRESULT hr;
4337 BYTE *data;
4338 LONG ref;
4340 static const short indices[] = {3, 4, 5};
4341 static const struct
4343 struct vec3 position;
4344 DWORD diffuse;
4346 quad[] =
4348 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
4349 {{-1.0f, 1.0f, 0.1f}, 0xffff0000},
4350 {{ 1.0f, 1.0f, 0.1f}, 0xffff0000},
4352 {{-1.0f, -1.0f, 0.1f}, 0xff00ff00},
4353 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
4354 {{ 1.0f, 1.0f, 0.1f}, 0xff00ff00},
4357 window = create_window();
4358 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4359 ok(!!d3d, "Failed to create a D3D object.\n");
4360 if (!(device = create_device(d3d, window, window, TRUE)))
4362 skip("Failed to create a D3D device, skipping tests.\n");
4363 goto done;
4366 /* Index and vertex buffers should always be creatable */
4367 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0,
4368 D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &vb, NULL);
4369 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
4370 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
4371 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
4372 memcpy(data, quad, sizeof(quad));
4373 hr = IDirect3DVertexBuffer9_Unlock(vb);
4374 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
4376 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0,
4377 D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
4378 ok(SUCCEEDED(hr), "Failed to create index buffer, hr %#x.\n", hr);
4379 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
4380 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
4381 memcpy(data, indices, sizeof(indices));
4382 hr = IDirect3DIndexBuffer9_Unlock(ib);
4383 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
4385 hr = IDirect3DDevice9_SetIndices(device, ib);
4386 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
4387 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
4388 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
4389 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
4390 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4391 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4392 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4394 /* Now destroy the bound index buffer and draw again */
4395 ref = IDirect3DIndexBuffer9_Release(ib);
4396 ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
4398 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4399 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
4401 hr = IDirect3DDevice9_BeginScene(device);
4402 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4403 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent
4404 * D3D from making assumptions about the indices or vertices. */
4405 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
4406 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4407 hr = IDirect3DDevice9_EndScene(device);
4408 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4410 color = getPixelColor(device, 160, 120);
4411 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1), "Got unexpected color 0x%08x.\n", color);
4412 color = getPixelColor(device, 480, 360);
4413 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1), "Got unexpected color 0x%08x.\n", color);
4415 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4416 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4418 /* Index buffer was already destroyed as part of the test */
4419 IDirect3DVertexBuffer9_Release(vb);
4420 refcount = IDirect3DDevice9_Release(device);
4421 ok(!refcount, "Device has %u references left.\n", refcount);
4422 done:
4423 IDirect3D9_Release(d3d);
4424 DestroyWindow(window);
4427 static void float_texture_test(void)
4429 IDirect3DTexture9 *texture;
4430 IDirect3DDevice9 *device;
4431 D3DLOCKED_RECT lr;
4432 IDirect3D9 *d3d;
4433 ULONG refcount;
4434 float *data;
4435 DWORD color;
4436 HWND window;
4437 HRESULT hr;
4439 static const float quad[] =
4441 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
4442 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
4443 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
4444 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4447 window = create_window();
4448 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4449 ok(!!d3d, "Failed to create a D3D object.\n");
4450 if (!(device = create_device(d3d, window, window, TRUE)))
4452 skip("Failed to create a D3D device, skipping tests.\n");
4453 goto done;
4456 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
4457 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK)
4459 skip("D3DFMT_R32F textures not supported\n");
4460 IDirect3DDevice9_Release(device);
4461 goto done;
4464 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F, D3DPOOL_MANAGED, &texture, NULL);
4465 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
4467 memset(&lr, 0, sizeof(lr));
4468 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4469 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
4470 data = lr.pBits;
4471 *data = 0.0;
4472 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4473 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
4475 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4476 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4477 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
4478 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4480 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4481 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
4483 hr = IDirect3DDevice9_BeginScene(device);
4484 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4485 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4486 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4487 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4488 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4489 hr = IDirect3DDevice9_EndScene(device);
4490 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4492 color = getPixelColor(device, 240, 320);
4493 ok(color == 0x0000ffff, "R32F with value 0.0 has color %08x, expected 0x0000ffff\n", color);
4495 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4496 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4498 IDirect3DTexture9_Release(texture);
4499 refcount = IDirect3DDevice9_Release(device);
4500 ok(!refcount, "Device has %u references left.\n", refcount);
4501 done:
4502 IDirect3D9_Release(d3d);
4503 DestroyWindow(window);
4506 static void g16r16_texture_test(void)
4508 IDirect3DTexture9 *texture;
4509 IDirect3DDevice9 *device;
4510 D3DLOCKED_RECT lr;
4511 IDirect3D9 *d3d;
4512 ULONG refcount;
4513 DWORD *data;
4514 DWORD color;
4515 HWND window;
4516 HRESULT hr;
4518 static const float quad[] =
4520 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
4521 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
4522 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
4523 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4526 window = create_window();
4527 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4528 ok(!!d3d, "Failed to create a D3D object.\n");
4529 if (!(device = create_device(d3d, window, window, TRUE)))
4531 skip("Failed to create a D3D device, skipping tests.\n");
4532 goto done;
4535 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
4536 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK)
4538 skip("D3DFMT_G16R16 textures not supported\n");
4539 IDirect3DDevice9_Release(device);
4540 goto done;
4543 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16, D3DPOOL_MANAGED, &texture, NULL);
4544 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
4546 memset(&lr, 0, sizeof(lr));
4547 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4548 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
4549 data = lr.pBits;
4550 *data = 0x0f00f000;
4551 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4552 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
4554 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4555 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4556 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
4557 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4559 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4560 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
4562 hr = IDirect3DDevice9_BeginScene(device);
4563 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4564 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4565 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4566 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4567 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4568 hr = IDirect3DDevice9_EndScene(device);
4569 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4571 color = getPixelColor(device, 240, 320);
4572 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
4573 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
4575 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4576 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4578 IDirect3DTexture9_Release(texture);
4579 refcount = IDirect3DDevice9_Release(device);
4580 ok(!refcount, "Device has %u references left.\n", refcount);
4581 done:
4582 IDirect3D9_Release(d3d);
4583 DestroyWindow(window);
4586 static void check_rect(IDirect3DDevice9 *device, RECT r, const char *message)
4588 LONG x_coords[2][2] =
4590 {r.left - 1, r.left + 1},
4591 {r.right + 1, r.right - 1},
4593 LONG y_coords[2][2] =
4595 {r.top - 1, r.top + 1},
4596 {r.bottom + 1, r.bottom - 1}
4598 unsigned int i, j, x_side, y_side;
4600 for (i = 0; i < 2; ++i)
4602 for (j = 0; j < 2; ++j)
4604 for (x_side = 0; x_side < 2; ++x_side)
4606 for (y_side = 0; y_side < 2; ++y_side)
4608 unsigned int x = x_coords[i][x_side], y = y_coords[j][y_side];
4609 DWORD color;
4610 DWORD expected = (x_side == 1 && y_side == 1) ? 0x00ffffff : 0;
4612 color = getPixelColor(device, x, y);
4613 ok(color == expected, "%s: Pixel (%d, %d) has color %08x, expected %08x\n",
4614 message, x, y, color, expected);
4621 struct projected_textures_test_run
4623 const char *message;
4624 DWORD flags;
4625 IDirect3DVertexDeclaration9 *decl;
4626 BOOL vs, ps;
4627 RECT rect;
4630 static void projected_textures_test(IDirect3DDevice9 *device,
4631 struct projected_textures_test_run tests[4])
4633 unsigned int i;
4635 static const DWORD vertex_shader[] =
4637 0xfffe0101, /* vs_1_1 */
4638 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4639 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
4640 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4641 0x00000001, 0xe00f0000, 0x90e40001, /* mov oT0, v1 */
4642 0x0000ffff /* end */
4644 static const DWORD pixel_shader[] =
4646 0xffff0103, /* ps_1_3 */
4647 0x00000042, 0xb00f0000, /* tex t0 */
4648 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4649 0x0000ffff /* end */
4651 IDirect3DVertexShader9 *vs = NULL;
4652 IDirect3DPixelShader9 *ps = NULL;
4653 IDirect3D9 *d3d;
4654 D3DCAPS9 caps;
4655 HRESULT hr;
4657 IDirect3DDevice9_GetDirect3D(device, &d3d);
4658 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4659 ok(SUCCEEDED(hr), "GetDeviceCaps failed (%08x)\n", hr);
4660 IDirect3D9_Release(d3d);
4662 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
4664 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader, &vs);
4665 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
4667 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 3))
4669 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader, &ps);
4670 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
4673 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0f, 0);
4674 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4676 hr = IDirect3DDevice9_BeginScene(device);
4677 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4679 for (i = 0; i < 4; ++i)
4681 DWORD value = 0xdeadbeef;
4682 static const float proj_quads[] =
4684 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4685 -1.0f, 0.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4686 0.0f, -1.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4687 0.0f, 0.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4689 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4690 0.0f, 0.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4691 1.0f, -1.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4692 1.0f, 0.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4694 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4695 -1.0f, 1.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4696 0.0f, 0.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4697 0.0f, 1.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4699 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4700 0.0f, 1.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4701 1.0f, 0.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4702 1.0f, 1.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4705 if (tests[i].vs)
4707 if (!vs)
4709 skip("Vertex shaders not supported, skipping\n");
4710 continue;
4712 hr = IDirect3DDevice9_SetVertexShader(device, vs);
4714 else
4715 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4716 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
4717 if (tests[i].ps)
4719 if (!ps)
4721 skip("Pixel shaders not supported, skipping\n");
4722 continue;
4724 hr = IDirect3DDevice9_SetPixelShader(device, ps);
4726 else
4727 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4728 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4730 hr = IDirect3DDevice9_SetVertexDeclaration(device, tests[i].decl);
4731 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4733 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, tests[i].flags);
4734 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4735 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, &value);
4736 ok(SUCCEEDED(hr) && value == tests[i].flags,
4737 "GetTextureStageState returned: hr %08x, value %08x.\n", hr, value);
4739 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
4740 &proj_quads[i * 4 * 7], 7 * sizeof(float));
4741 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4744 hr = IDirect3DDevice9_EndScene(device);
4745 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4747 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4748 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4749 if (vs) IDirect3DVertexShader9_Release(vs);
4750 if (ps) IDirect3DPixelShader9_Release(ps);
4752 for (i = 0; i < 4; ++i)
4754 if ((!tests[i].vs || vs) && (!tests[i].ps || ps))
4755 check_rect(device, tests[i].rect, tests[i].message);
4758 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4759 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4762 static void texture_transform_flags_test(void)
4764 HRESULT hr;
4765 IDirect3D9 *d3d;
4766 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
4767 D3DCAPS9 caps;
4768 IDirect3DTexture9 *texture = NULL;
4769 IDirect3DVolumeTexture9 *volume = NULL;
4770 IDirect3DDevice9 *device;
4771 unsigned int x, y, z;
4772 D3DLOCKED_RECT lr;
4773 D3DLOCKED_BOX lb;
4774 D3DCOLOR color;
4775 ULONG refcount;
4776 HWND window;
4777 UINT w, h;
4778 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3, *decl4;
4780 static const D3DVERTEXELEMENT9 decl_elements[] = {
4781 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4782 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4783 D3DDECL_END()
4785 static const D3DVERTEXELEMENT9 decl_elements2[] = {
4786 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4787 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4788 D3DDECL_END()
4790 static const D3DVERTEXELEMENT9 decl_elements3[] = {
4791 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4792 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4793 D3DDECL_END()
4795 static const D3DVERTEXELEMENT9 decl_elements4[] = {
4796 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4797 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4798 D3DDECL_END()
4800 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
4801 0x00, 0xff, 0x00, 0x00,
4802 0x00, 0x00, 0x00, 0x00,
4803 0x00, 0x00, 0x00, 0x00};
4804 static const D3DMATRIX identity =
4806 1.0f, 0.0f, 0.0f, 0.0f,
4807 0.0f, 1.0f, 0.0f, 0.0f,
4808 0.0f, 0.0f, 1.0f, 0.0f,
4809 0.0f, 0.0f, 0.0f, 1.0f,
4810 }}};
4812 window = create_window();
4813 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4814 ok(!!d3d, "Failed to create a D3D object.\n");
4815 if (!(device = create_device(d3d, window, window, TRUE)))
4817 skip("Failed to create a D3D device, skipping tests.\n");
4818 goto done;
4821 memset(&lr, 0, sizeof(lr));
4822 memset(&lb, 0, sizeof(lb));
4823 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
4824 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK)
4825 fmt = D3DFMT_A16B16G16R16;
4827 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4828 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4829 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
4830 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4831 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
4832 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4833 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements4, &decl4);
4834 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4835 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
4836 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
4837 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
4838 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
4839 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
4840 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
4841 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4842 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
4843 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
4844 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
4845 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
4846 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
4847 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
4848 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
4849 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
4850 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState(D3DTSS_COLOROP) returned %08x\n", hr);
4851 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
4852 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState(D3DTSS_COLORARG1) returned %08x\n", hr);
4853 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4854 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
4855 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4856 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4858 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4859 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
4860 w = min(1024, caps.MaxTextureWidth);
4861 h = min(1024, caps.MaxTextureHeight);
4862 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
4863 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
4864 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4865 if (!texture)
4867 skip("Failed to create the test texture.\n");
4868 IDirect3DDevice9_Release(device);
4869 goto done;
4872 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
4873 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
4874 * 1.0 in red and green for the x and y coords
4876 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4877 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
4878 for(y = 0; y < h; y++) {
4879 for(x = 0; x < w; x++) {
4880 double r_f = (double) y / (double) h;
4881 double g_f = (double) x / (double) w;
4882 if(fmt == D3DFMT_A16B16G16R16) {
4883 unsigned short r, g;
4884 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
4885 r = (unsigned short) (r_f * 65536.0);
4886 g = (unsigned short) (g_f * 65536.0);
4887 dst[0] = r;
4888 dst[1] = g;
4889 dst[2] = 0;
4890 dst[3] = 65535;
4891 } else {
4892 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
4893 unsigned char r = (unsigned char) (r_f * 255.0);
4894 unsigned char g = (unsigned char) (g_f * 255.0);
4895 dst[0] = 0;
4896 dst[1] = g;
4897 dst[2] = r;
4898 dst[3] = 255;
4902 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4903 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
4904 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4905 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4907 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4908 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4909 hr = IDirect3DDevice9_BeginScene(device);
4910 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4911 if(SUCCEEDED(hr))
4913 static const float quad1[] =
4915 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f,
4916 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4917 0.0f, -1.0f, 0.1f, 1.0f, 1.0f,
4918 0.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4920 static const float quad2[] =
4922 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4923 -1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4924 0.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4925 0.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4927 static const float quad3[] =
4929 0.0f, 0.0f, 0.1f, 0.5f, 0.5f,
4930 0.0f, 1.0f, 0.1f, 0.5f, 0.5f,
4931 1.0f, 0.0f, 0.1f, 0.5f, 0.5f,
4932 1.0f, 1.0f, 0.1f, 0.5f, 0.5f,
4934 static const float quad4[] =
4936 320.0f, 480.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4937 320.0f, 240.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4938 640.0f, 480.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4939 640.0f, 240.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4941 D3DMATRIX mat =
4943 0.0f, 0.0f, 0.0f, 0.0f,
4944 0.0f, 0.0f, 0.0f, 0.0f,
4945 0.0f, 0.0f, 0.0f, 0.0f,
4946 0.0f, 0.0f, 0.0f, 0.0f,
4947 }}};
4949 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
4950 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4951 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4952 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4953 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4955 /* What happens with transforms enabled? */
4956 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4957 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4958 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4959 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4961 /* What happens if 4 coords are used, but only 2 given ?*/
4962 U(mat).m[2][0] = 1.0f;
4963 U(mat).m[3][1] = 1.0f;
4964 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4965 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4966 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
4967 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4968 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4969 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4971 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
4972 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
4973 * due to the coords in the vertices. (turns out red, indeed)
4975 memset(&mat, 0, sizeof(mat));
4976 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4977 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4978 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
4979 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4980 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4981 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4982 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4983 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4985 hr = IDirect3DDevice9_EndScene(device);
4986 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4988 color = getPixelColor(device, 160, 360);
4989 ok(color_match(color, 0x00ffff00, 1), "quad 1 has color %08x, expected 0x00ffff00\n", color);
4990 color = getPixelColor(device, 160, 120);
4991 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4992 color = getPixelColor(device, 480, 120);
4993 ok(color_match(color, 0x0000ff00, 1), "quad 3 has color %08x, expected 0x0000ff00\n", color);
4994 color = getPixelColor(device, 480, 360);
4995 ok(color_match(color, 0x00ff0000, 1), "quad 4 has color %08x, expected 0x00ff0000\n", color);
4996 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4997 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4999 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
5000 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5002 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5003 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5004 hr = IDirect3DDevice9_BeginScene(device);
5005 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
5006 if(SUCCEEDED(hr))
5008 static const float quad1[] =
5010 -1.0f, -1.0f, 0.1f, 0.8f, 0.2f,
5011 -1.0f, 0.0f, 0.1f, 0.8f, 0.2f,
5012 0.0f, -1.0f, 0.1f, 0.8f, 0.2f,
5013 0.0f, 0.0f, 0.1f, 0.8f, 0.2f,
5015 static const float quad2[] =
5017 -1.0f, 0.0f, 0.1f, 0.5f, 1.0f,
5018 -1.0f, 1.0f, 0.1f, 0.5f, 1.0f,
5019 0.0f, 0.0f, 0.1f, 0.5f, 1.0f,
5020 0.0f, 1.0f, 0.1f, 0.5f, 1.0f,
5022 static const float quad3[] =
5024 0.0f, 0.0f, 0.1f, 0.5f, 1.0f,
5025 0.0f, 1.0f, 0.1f, 0.5f, 1.0f,
5026 1.0f, 0.0f, 0.1f, 0.5f, 1.0f,
5027 1.0f, 1.0f, 0.1f, 0.5f, 1.0f,
5029 static const float quad4[] =
5031 0.0f, -1.0f, 0.1f, 0.8f, 0.2f,
5032 0.0f, 0.0f, 0.1f, 0.8f, 0.2f,
5033 1.0f, -1.0f, 0.1f, 0.8f, 0.2f,
5034 1.0f, 0.0f, 0.1f, 0.8f, 0.2f,
5036 D3DMATRIX mat =
5038 0.0f, 0.0f, 0.0f, 0.0f,
5039 0.0f, 0.0f, 0.0f, 0.0f,
5040 0.0f, 1.0f, 0.0f, 0.0f,
5041 0.0f, 0.0f, 0.0f, 0.0f,
5042 }}};
5044 /* What happens to the default 1 in the 3rd coordinate if it is disabled? */
5045 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5046 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5047 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
5048 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5050 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
5051 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
5053 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
5054 * it behaves like COUNT2 because normal textures require 2 coords. */
5055 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
5056 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5057 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
5058 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
5060 /* Just to be sure, the same as quad2 above */
5061 memset(&mat, 0, sizeof(mat));
5062 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5063 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5064 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
5065 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5066 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
5067 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
5069 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
5070 * used? And what happens to the first? */
5071 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
5072 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5073 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
5074 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
5076 hr = IDirect3DDevice9_EndScene(device);
5077 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
5079 color = getPixelColor(device, 160, 360);
5080 ok(color_match(color, 0x00ff0000, 1), "quad 1 has color %08x, expected 0x00ff0000\n", color);
5081 color = getPixelColor(device, 160, 120);
5082 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
5083 color = getPixelColor(device, 480, 120);
5084 ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
5085 "quad 3 has color %08x, expected 0x00ff8000\n", color);
5086 color = getPixelColor(device, 480, 360);
5087 ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00ff0000, 1),
5088 "quad 4 has color %08x, expected 0x0033cc00\n", color);
5089 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5090 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5092 IDirect3DTexture9_Release(texture);
5094 /* Test projected textures, without any fancy matrices */
5095 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
5096 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5097 if (SUCCEEDED(hr))
5099 struct projected_textures_test_run projected_tests_1[4] =
5102 "D3DTTFF_COUNT4 | D3DTTFF_PROJECTED - bottom left",
5103 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED,
5104 decl3,
5105 FALSE, TRUE,
5106 {120, 300, 240, 390},
5109 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED - bottom right",
5110 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
5111 decl3,
5112 FALSE, TRUE,
5113 {400, 360, 480, 420},
5115 /* Try with some invalid values */
5117 "0xffffffff (draws like COUNT4 | PROJECTED) - top left",
5118 0xffffffff,
5119 decl3,
5120 FALSE, TRUE,
5121 {120, 60, 240, 150}
5124 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (draws non-projected) - top right",
5125 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
5126 decl4,
5127 FALSE, TRUE,
5128 {340, 210, 360, 225},
5131 struct projected_textures_test_run projected_tests_2[4] =
5134 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED, texcoord has 4 components) - bottom left",
5135 D3DTTFF_PROJECTED,
5136 decl3,
5137 FALSE, TRUE,
5138 {120, 300, 240, 390},
5141 "D3DTTFF_PROJECTED (like COUNT3 | PROJECTED, texcoord has only 3 components) - bottom right",
5142 D3DTTFF_PROJECTED,
5143 decl,
5144 FALSE, TRUE,
5145 {400, 360, 480, 420},
5148 "0xffffffff (like COUNT3 | PROJECTED, texcoord has only 3 components) - top left",
5149 0xffffffff,
5150 decl,
5151 FALSE, TRUE,
5152 {80, 120, 160, 180},
5155 "D3DTTFF_COUNT1 (draws non-projected) - top right",
5156 D3DTTFF_COUNT1,
5157 decl4,
5158 FALSE, TRUE,
5159 {340, 210, 360, 225},
5162 struct projected_textures_test_run projected_tests_3[4] =
5165 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom left",
5166 D3DTTFF_PROJECTED,
5167 decl3,
5168 TRUE, FALSE,
5169 {120, 300, 240, 390},
5172 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom right",
5173 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
5174 decl3,
5175 TRUE, TRUE,
5176 {440, 300, 560, 390},
5179 "0xffffffff (like COUNT4 | PROJECTED) - top left",
5180 0xffffffff,
5181 decl3,
5182 TRUE, TRUE,
5183 {120, 60, 240, 150},
5186 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - top right",
5187 D3DTTFF_PROJECTED,
5188 decl3,
5189 FALSE, FALSE,
5190 {440, 60, 560, 150},
5194 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
5195 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5197 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5198 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
5199 for(x = 0; x < 4; x++) {
5200 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
5202 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5203 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
5204 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5205 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
5207 projected_textures_test(device, projected_tests_1);
5208 projected_textures_test(device, projected_tests_2);
5209 projected_textures_test(device, projected_tests_3);
5211 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5212 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
5213 IDirect3DTexture9_Release(texture);
5216 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
5217 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5218 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
5219 * Thus watch out if sampling from texels between 0 and 1.
5221 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
5222 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
5223 "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
5224 if(!volume) {
5225 skip("Failed to create a volume texture\n");
5226 goto out;
5229 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
5230 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
5231 for(z = 0; z < 32; z++) {
5232 for(y = 0; y < 32; y++) {
5233 for(x = 0; x < 32; x++) {
5234 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
5235 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
5236 float r_f = (float) x / 31.0;
5237 float g_f = (float) y / 31.0;
5238 float b_f = (float) z / 31.0;
5240 if(fmt == D3DFMT_A16B16G16R16) {
5241 unsigned short *mem_s = mem;
5242 mem_s[0] = r_f * 65535.0;
5243 mem_s[1] = g_f * 65535.0;
5244 mem_s[2] = b_f * 65535.0;
5245 mem_s[3] = 65535;
5246 } else {
5247 unsigned char *mem_c = mem;
5248 mem_c[0] = b_f * 255.0;
5249 mem_c[1] = g_f * 255.0;
5250 mem_c[2] = r_f * 255.0;
5251 mem_c[3] = 255;
5256 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
5257 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
5259 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
5260 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
5262 hr = IDirect3DDevice9_BeginScene(device);
5263 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
5264 if(SUCCEEDED(hr))
5266 static const float quad1[] =
5268 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5269 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5270 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5271 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5273 static const float quad2[] =
5275 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5276 -1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5277 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5278 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5280 static const float quad3[] =
5282 0.0f, 0.0f, 0.1f, 0.0f, 0.0f,
5283 0.0f, 1.0f, 0.1f, 0.0f, 0.0f,
5284 1.0f, 0.0f, 0.1f, 0.0f, 0.0f,
5285 1.0f, 1.0f, 0.1f, 0.0f, 0.0f,
5287 static const float quad4[] =
5289 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5290 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5291 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5292 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5294 D3DMATRIX mat =
5296 1.0f, 0.0f, 0.0f, 0.0f,
5297 0.0f, 0.0f, 1.0f, 0.0f,
5298 0.0f, 1.0f, 0.0f, 0.0f,
5299 0.0f, 0.0f, 0.0f, 1.0f,
5300 }}};
5301 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5302 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5304 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
5305 * values
5307 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5308 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5309 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
5310 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5311 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5312 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5314 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
5315 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
5316 * otherwise the w will be missing(blue).
5317 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
5318 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3. */
5319 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
5320 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5321 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5322 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5324 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
5325 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
5326 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5327 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
5328 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5329 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5330 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5331 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
5332 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5334 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
5335 * disable. ATI extends it up to the amount of values needed for the volume texture
5337 memset(&mat, 0, sizeof(mat));
5338 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5339 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5340 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
5341 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5342 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5343 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5344 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5345 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5347 hr = IDirect3DDevice9_EndScene(device);
5348 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
5351 color = getPixelColor(device, 160, 360);
5352 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
5353 color = getPixelColor(device, 160, 120);
5354 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
5355 "quad 2 has color %08x, expected 0x00ffff00\n", color);
5356 color = getPixelColor(device, 480, 120);
5357 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
5358 color = getPixelColor(device, 480, 360);
5359 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
5361 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5362 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5364 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
5365 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5366 hr = IDirect3DDevice9_BeginScene(device);
5367 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
5368 if(SUCCEEDED(hr))
5370 static const float quad1[] =
5372 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5373 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5374 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5375 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5377 static const float quad2[] =
5379 -1.0f, 0.0f, 0.1f,
5380 -1.0f, 1.0f, 0.1f,
5381 0.0f, 0.0f, 0.1f,
5382 0.0f, 1.0f, 0.1f,
5384 static const float quad3[] =
5386 0.0f, 0.0f, 0.1f, 1.0f,
5387 0.0f, 1.0f, 0.1f, 1.0f,
5388 1.0f, 0.0f, 0.1f, 1.0f,
5389 1.0f, 1.0f, 0.1f, 1.0f,
5391 static const D3DMATRIX mat =
5393 0.0f, 0.0f, 0.0f, 0.0f,
5394 0.0f, 0.0f, 0.0f, 0.0f,
5395 0.0f, 0.0f, 0.0f, 0.0f,
5396 0.0f, 1.0f, 0.0f, 0.0f,
5397 }}};
5398 static const D3DMATRIX mat2 =
5400 0.0f, 0.0f, 0.0f, 1.0f,
5401 1.0f, 0.0f, 0.0f, 0.0f,
5402 0.0f, 1.0f, 0.0f, 0.0f,
5403 0.0f, 0.0f, 1.0f, 0.0f,
5404 }}};
5405 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5406 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5408 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
5409 * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
5410 * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
5411 * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
5412 * 4th *input* coordinate.
5414 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5415 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5416 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
5417 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5418 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5419 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5421 /* None passed */
5422 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
5423 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5424 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5425 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5426 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5427 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5429 /* 4 used, 1 passed */
5430 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5431 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5432 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat2);
5433 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5434 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
5435 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5437 hr = IDirect3DDevice9_EndScene(device);
5438 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
5440 color = getPixelColor(device, 160, 360);
5441 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
5442 color = getPixelColor(device, 160, 120);
5443 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
5444 color = getPixelColor(device, 480, 120);
5445 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
5446 /* Quad4: unused */
5448 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5449 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5451 IDirect3DVolumeTexture9_Release(volume);
5453 out:
5454 IDirect3DVertexDeclaration9_Release(decl);
5455 IDirect3DVertexDeclaration9_Release(decl2);
5456 IDirect3DVertexDeclaration9_Release(decl3);
5457 IDirect3DVertexDeclaration9_Release(decl4);
5458 refcount = IDirect3DDevice9_Release(device);
5459 ok(!refcount, "Device has %u references left.\n", refcount);
5460 done:
5461 IDirect3D9_Release(d3d);
5462 DestroyWindow(window);
5465 static void texdepth_test(void)
5467 IDirect3DPixelShader9 *shader;
5468 IDirect3DDevice9 *device;
5469 IDirect3D9 *d3d;
5470 ULONG refcount;
5471 D3DCAPS9 caps;
5472 DWORD color;
5473 HWND window;
5474 HRESULT hr;
5476 static const float texdepth_test_data1[] = { 0.25f, 2.0f, 0.0f, 0.0f};
5477 static const float texdepth_test_data2[] = { 0.25f, 0.5f, 0.0f, 0.0f};
5478 static const float texdepth_test_data3[] = {-1.00f, 0.1f, 0.0f, 0.0f};
5479 static const float texdepth_test_data4[] = {-0.25f, -0.5f, 0.0f, 0.0f};
5480 static const float texdepth_test_data5[] = { 1.00f, -0.1f, 0.0f, 0.0f};
5481 static const float texdepth_test_data6[] = { 1.00f, 0.5f, 0.0f, 0.0f};
5482 static const float texdepth_test_data7[] = { 0.50f, 0.0f, 0.0f, 0.0f};
5483 static const DWORD shader_code[] =
5485 0xffff0104, /* ps_1_4 */
5486 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
5487 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
5488 0x0000fffd, /* phase */
5489 0x00000057, 0x800f0005, /* texdepth r5 */
5490 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
5491 0x0000ffff /* end */
5493 static const float vertex[] =
5495 -1.0f, -1.0f, 0.0f,
5496 -1.0f, 1.0f, 0.0f,
5497 1.0f, -1.0f, 1.0f,
5498 1.0f, 1.0f, 1.0f,
5501 window = create_window();
5502 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5503 ok(!!d3d, "Failed to create a D3D object.\n");
5504 if (!(device = create_device(d3d, window, window, TRUE)))
5506 skip("Failed to create a D3D device, skipping tests.\n");
5507 goto done;
5510 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5511 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5512 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
5514 skip("No ps_1_4 support, skipping tests.\n");
5515 IDirect3DDevice9_Release(device);
5516 goto done;
5519 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5520 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5522 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
5523 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5524 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5525 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
5526 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
5527 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5528 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
5529 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5530 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
5531 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5532 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5533 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
5535 /* Fill the depth buffer with a gradient */
5536 hr = IDirect3DDevice9_BeginScene(device);
5537 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5538 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5539 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5540 hr = IDirect3DDevice9_EndScene(device);
5541 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5543 /* Now perform the actual tests. Same geometry, but with the shader */
5544 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
5545 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5546 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
5547 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5548 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5549 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5551 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
5552 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5553 hr = IDirect3DDevice9_BeginScene(device);
5554 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5555 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5556 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5557 hr = IDirect3DDevice9_EndScene(device);
5558 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5560 color = getPixelColor(device, 158, 240);
5561 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
5562 color = getPixelColor(device, 162, 240);
5563 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
5565 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5566 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5568 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5569 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5571 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
5572 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5573 hr = IDirect3DDevice9_BeginScene(device);
5574 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5575 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5576 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5577 hr = IDirect3DDevice9_EndScene(device);
5578 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5580 color = getPixelColor(device, 318, 240);
5581 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
5582 color = getPixelColor(device, 322, 240);
5583 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
5585 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5586 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5588 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
5589 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5591 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
5592 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5593 hr = IDirect3DDevice9_BeginScene(device);
5594 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5595 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5596 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5597 hr = IDirect3DDevice9_EndScene(device);
5598 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5600 color = getPixelColor(device, 1, 240);
5601 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
5603 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5604 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5606 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
5607 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5609 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
5610 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5611 hr = IDirect3DDevice9_BeginScene(device);
5612 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5613 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5614 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5615 hr = IDirect3DDevice9_EndScene(device);
5616 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5618 color = getPixelColor(device, 318, 240);
5619 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
5620 color = getPixelColor(device, 322, 240);
5621 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
5623 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5624 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5626 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5627 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5629 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
5630 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5631 hr = IDirect3DDevice9_BeginScene(device);
5632 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5633 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5634 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5635 hr = IDirect3DDevice9_EndScene(device);
5636 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5638 color = getPixelColor(device, 1, 240);
5639 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
5641 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5642 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5644 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
5645 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5647 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
5648 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5649 hr = IDirect3DDevice9_BeginScene(device);
5650 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5651 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5652 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5653 hr = IDirect3DDevice9_EndScene(device);
5654 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5656 color = getPixelColor(device, 638, 240);
5657 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
5659 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5660 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5662 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
5663 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5665 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
5666 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5667 hr = IDirect3DDevice9_BeginScene(device);
5668 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5669 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5670 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5671 hr = IDirect3DDevice9_EndScene(device);
5672 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5674 color = getPixelColor(device, 638, 240);
5675 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
5677 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5678 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5680 IDirect3DPixelShader9_Release(shader);
5681 refcount = IDirect3DDevice9_Release(device);
5682 ok(!refcount, "Device has %u references left.\n", refcount);
5683 done:
5684 IDirect3D9_Release(d3d);
5685 DestroyWindow(window);
5688 static void texkill_test(void)
5690 IDirect3DPixelShader9 *shader;
5691 IDirect3DDevice9 *device;
5692 IDirect3D9 *d3d;
5693 ULONG refcount;
5694 D3DCAPS9 caps;
5695 DWORD color;
5696 HWND window;
5697 HRESULT hr;
5699 static const float vertex[] =
5701 /* bottom top right left */
5702 -1.0f, -1.0f, 1.0f, -0.1f, 0.9f, 0.9f, -0.1f,
5703 -1.0f, 1.0f, 1.0f, -0.1f, 0.9f, -0.1f, 0.9f,
5704 1.0f, -1.0f, 0.0f, 0.9f, -0.1f, 0.9f, -0.1f,
5705 1.0f, 1.0f, 0.0f, 0.9f, -0.1f, -0.1f, 0.9f,
5707 static const DWORD shader_code_11[] =
5709 0xffff0101, /* ps_1_1 */
5710 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
5711 0x00000041, 0xb00f0000, /* texkill t0 */
5712 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5713 0x0000ffff /* end */
5715 static const DWORD shader_code_20[] =
5717 0xffff0200, /* ps_2_0 */
5718 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
5719 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
5720 0x01000041, 0xb00f0000, /* texkill t0 */
5721 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
5722 0x0000ffff /* end */
5725 window = create_window();
5726 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5727 ok(!!d3d, "Failed to create a D3D object.\n");
5728 if (!(device = create_device(d3d, window, window, TRUE)))
5730 skip("Failed to create a D3D device, skipping tests.\n");
5731 goto done;
5734 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5735 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5736 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
5738 skip("No ps_1_1 support, skipping tests.\n");
5739 IDirect3DDevice9_Release(device);
5740 goto done;
5743 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
5744 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5745 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
5746 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5748 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5749 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5750 hr = IDirect3DDevice9_BeginScene(device);
5751 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5752 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
5753 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5754 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
5755 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5756 hr = IDirect3DDevice9_EndScene(device);
5757 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5759 color = getPixelColor(device, 63, 46);
5760 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
5761 color = getPixelColor(device, 66, 46);
5762 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
5763 color = getPixelColor(device, 63, 49);
5764 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
5765 color = getPixelColor(device, 66, 49);
5766 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
5768 color = getPixelColor(device, 578, 46);
5769 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5770 color = getPixelColor(device, 575, 46);
5771 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5772 color = getPixelColor(device, 578, 49);
5773 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
5774 color = getPixelColor(device, 575, 49);
5775 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5777 color = getPixelColor(device, 63, 430);
5778 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5779 color = getPixelColor(device, 63, 433);
5780 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5781 color = getPixelColor(device, 66, 433);
5782 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
5783 color = getPixelColor(device, 66, 430);
5784 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5786 color = getPixelColor(device, 578, 430);
5787 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5788 color = getPixelColor(device, 578, 433);
5789 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5790 color = getPixelColor(device, 575, 433);
5791 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
5792 color = getPixelColor(device, 575, 430);
5793 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5795 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5796 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5798 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5799 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5800 IDirect3DPixelShader9_Release(shader);
5802 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5803 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5804 if (FAILED(IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader)))
5806 skip("Failed to create 2.0 test shader, most likely not supported.\n");
5807 IDirect3DDevice9_Release(device);
5808 goto done;
5811 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5812 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5813 hr = IDirect3DDevice9_BeginScene(device);
5814 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5815 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
5816 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5817 hr = IDirect3DDevice9_EndScene(device);
5818 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5820 color = getPixelColor(device, 63, 46);
5821 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
5822 color = getPixelColor(device, 66, 46);
5823 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
5824 color = getPixelColor(device, 63, 49);
5825 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
5826 color = getPixelColor(device, 66, 49);
5827 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
5829 color = getPixelColor(device, 578, 46);
5830 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5831 color = getPixelColor(device, 575, 46);
5832 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5833 color = getPixelColor(device, 578, 49);
5834 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5835 color = getPixelColor(device, 575, 49);
5836 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5838 color = getPixelColor(device, 63, 430);
5839 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5840 color = getPixelColor(device, 63, 433);
5841 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5842 color = getPixelColor(device, 66, 433);
5843 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5844 color = getPixelColor(device, 66, 430);
5845 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5847 color = getPixelColor(device, 578, 430);
5848 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5849 color = getPixelColor(device, 578, 433);
5850 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5851 color = getPixelColor(device, 575, 433);
5852 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5853 color = getPixelColor(device, 575, 430);
5854 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5856 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5857 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5859 IDirect3DPixelShader9_Release(shader);
5860 refcount = IDirect3DDevice9_Release(device);
5861 ok(!refcount, "Device has %u references left.\n", refcount);
5862 done:
5863 IDirect3D9_Release(d3d);
5864 DestroyWindow(window);
5867 static void autogen_mipmap_test(void)
5869 IDirect3DTexture9 *texture = NULL;
5870 IDirect3DSurface9 *surface;
5871 IDirect3DDevice9 *device;
5872 unsigned int x, y;
5873 D3DLOCKED_RECT lr;
5874 IDirect3D9 *d3d;
5875 D3DCOLOR color;
5876 ULONG refcount;
5877 HWND window;
5878 HRESULT hr;
5880 static const RECT r1 = {256, 256, 512, 512};
5881 static const RECT r2 = {512, 256, 768, 512};
5882 static const RECT r3 = {256, 512, 512, 768};
5883 static const RECT r4 = {512, 512, 768, 768};
5884 static const float quad[] =
5886 -0.5f, -0.5f, 0.1f, 0.0f, 0.0f,
5887 -0.5f, 0.5f, 0.1f, 0.0f, 1.0f,
5888 0.5f, -0.5f, 0.1f, 1.0f, 0.0f,
5889 0.5f, 0.5f, 0.1f, 1.0f, 1.0f,
5892 window = create_window();
5893 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5894 ok(!!d3d, "Failed to create a D3D object.\n");
5895 if (!(device = create_device(d3d, window, window, TRUE)))
5897 skip("Failed to create a D3D device, skipping tests.\n");
5898 goto done;
5901 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
5902 D3DFMT_X8R8G8B8, D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK)
5904 skip("No autogenmipmap support.\n");
5905 IDirect3DDevice9_Release(device);
5906 goto done;
5909 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 1.0f, 0);
5910 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5912 /* Make the mipmap big, so that a smaller mipmap is used
5914 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
5915 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
5916 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5918 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5919 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
5920 memset(&lr, 0, sizeof(lr));
5921 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5922 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
5923 for(y = 0; y < 1024; y++) {
5924 for(x = 0; x < 1024; x++) {
5925 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
5926 POINT pt;
5928 pt.x = x;
5929 pt.y = y;
5930 if(PtInRect(&r1, pt)) {
5931 *dst = 0xffff0000;
5932 } else if(PtInRect(&r2, pt)) {
5933 *dst = 0xff00ff00;
5934 } else if(PtInRect(&r3, pt)) {
5935 *dst = 0xff0000ff;
5936 } else if(PtInRect(&r4, pt)) {
5937 *dst = 0xff000000;
5938 } else {
5939 *dst = 0xffffffff;
5943 hr = IDirect3DSurface9_UnlockRect(surface);
5944 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
5945 IDirect3DSurface9_Release(surface);
5947 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5948 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5949 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
5950 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
5951 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5952 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
5954 hr = IDirect3DDevice9_BeginScene(device);
5955 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5956 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5957 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5958 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5959 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5960 hr = IDirect3DDevice9_EndScene(device);
5961 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5962 IDirect3DTexture9_Release(texture);
5964 color = getPixelColor(device, 200, 200);
5965 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
5966 color = getPixelColor(device, 280, 200);
5967 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
5968 color = getPixelColor(device, 360, 200);
5969 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
5970 color = getPixelColor(device, 440, 200);
5971 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5972 color = getPixelColor(device, 200, 270);
5973 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
5974 color = getPixelColor(device, 280, 270);
5975 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
5976 color = getPixelColor(device, 360, 270);
5977 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
5978 color = getPixelColor(device, 440, 270);
5979 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5980 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5981 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5983 refcount = IDirect3DDevice9_Release(device);
5984 ok(!refcount, "Device has %u references left.\n", refcount);
5985 done:
5986 IDirect3D9_Release(d3d);
5987 DestroyWindow(window);
5990 static void test_constant_clamp_vs(void)
5992 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
5993 IDirect3DVertexDeclaration9 *decl;
5994 IDirect3DDevice9 *device;
5995 IDirect3D9 *d3d;
5996 D3DCOLOR color;
5997 ULONG refcount;
5998 D3DCAPS9 caps;
5999 HWND window;
6000 HRESULT hr;
6002 static const DWORD shader_code_11[] =
6004 0xfffe0101, /* vs_1_1 */
6005 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6006 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6007 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
6008 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6009 0x0000ffff /* end */
6011 static const DWORD shader_code_11_2[] =
6013 0xfffe0101, /* vs_1_1 */
6014 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
6015 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
6016 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6017 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6018 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
6019 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6020 0x0000ffff /* end */
6022 static const DWORD shader_code_20[] =
6024 0xfffe0200, /* vs_2_0 */
6025 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6026 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6027 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
6028 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6029 0x0000ffff /* end */
6031 static const DWORD shader_code_20_2[] =
6033 0xfffe0200, /* vs_2_0 */
6034 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
6035 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
6036 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6037 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6038 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
6039 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6040 0x0000ffff /* end */
6042 static const D3DVERTEXELEMENT9 decl_elements[] =
6044 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6045 D3DDECL_END()
6047 static const float quad1[] =
6049 -1.0f, -1.0f, 0.1f,
6050 -1.0f, 0.0f, 0.1f,
6051 0.0f, -1.0f, 0.1f,
6052 0.0f, 0.0f, 0.1f,
6054 static const float quad2[] =
6056 0.0f, -1.0f, 0.1f,
6057 0.0f, 0.0f, 0.1f,
6058 1.0f, -1.0f, 0.1f,
6059 1.0f, 0.0f, 0.1f,
6061 static const float quad3[] =
6063 0.0f, 0.0f, 0.1f,
6064 0.0f, 1.0f, 0.1f,
6065 1.0f, 0.0f, 0.1f,
6066 1.0f, 1.0f, 0.1f,
6068 static const float quad4[] =
6070 -1.0f, 0.0f, 0.1f,
6071 -1.0f, 1.0f, 0.1f,
6072 0.0f, 0.0f, 0.1f,
6073 0.0f, 1.0f, 0.1f,
6075 static const float test_data_c1[4] = { 1.25f, -0.50f, -1.50f, 1.0f};
6076 static const float test_data_c2[4] = {-0.50f, 1.25f, 2.00f, 1.0f};
6078 window = create_window();
6079 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6080 ok(!!d3d, "Failed to create a D3D object.\n");
6081 if (!(device = create_device(d3d, window, window, TRUE)))
6083 skip("Failed to create a D3D device, skipping tests.\n");
6084 goto done;
6087 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6088 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6089 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
6091 skip("No vs_1_1 support, skipping tests.\n");
6092 IDirect3DDevice9_Release(device);
6093 goto done;
6096 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
6097 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6099 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
6100 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6101 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
6102 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6103 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
6104 if(FAILED(hr)) shader_20 = NULL;
6105 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
6106 if(FAILED(hr)) shader_20_2 = NULL;
6107 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
6108 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6110 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
6111 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
6112 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
6113 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
6114 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6115 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6117 hr = IDirect3DDevice9_BeginScene(device);
6118 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6120 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
6121 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
6122 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
6123 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6125 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
6126 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
6127 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
6128 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6130 if (shader_20)
6132 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
6133 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
6134 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
6135 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6138 if (shader_20_2)
6140 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
6141 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
6142 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
6143 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6146 hr = IDirect3DDevice9_EndScene(device);
6147 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6149 color = getPixelColor(device, 160, 360);
6150 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6151 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
6152 color = getPixelColor(device, 480, 360);
6153 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6154 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
6155 if(shader_20) {
6156 color = getPixelColor(device, 480, 120);
6157 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6158 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
6160 if(shader_20_2) {
6161 color = getPixelColor(device, 160, 120);
6162 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6163 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
6165 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6166 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6168 IDirect3DVertexDeclaration9_Release(decl);
6169 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
6170 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
6171 IDirect3DVertexShader9_Release(shader_11_2);
6172 IDirect3DVertexShader9_Release(shader_11);
6173 refcount = IDirect3DDevice9_Release(device);
6174 ok(!refcount, "Device has %u references left.\n", refcount);
6175 done:
6176 IDirect3D9_Release(d3d);
6177 DestroyWindow(window);
6180 static void constant_clamp_ps_test(void)
6182 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
6183 IDirect3DDevice9 *device;
6184 IDirect3D9 *d3d;
6185 ULONG refcount;
6186 D3DCAPS9 caps;
6187 DWORD color;
6188 HWND window;
6189 HRESULT hr;
6191 static const DWORD shader_code_11[] =
6193 0xffff0101, /* ps_1_1 */
6194 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6195 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6196 0x0000ffff /* end */
6198 static const DWORD shader_code_12[] =
6200 0xffff0102, /* ps_1_2 */
6201 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6202 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6203 0x0000ffff /* end */
6205 /* Skip 1.3 shaders because we have only 4 quads (ok, could make them
6206 * smaller if needed). 1.2 and 1.4 shaders behave the same, so it's
6207 * unlikely that 1.3 shaders are different. During development of this
6208 * test, 1.3 shaders were verified too. */
6209 static const DWORD shader_code_14[] =
6211 0xffff0104, /* ps_1_4 */
6212 /* Try to make one constant local. It gets clamped too, although the
6213 * binary contains the bigger numbers. */
6214 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
6215 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6216 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6217 0x0000ffff /* end */
6219 static const DWORD shader_code_20[] =
6221 0xffff0200, /* ps_2_0 */
6222 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6223 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6224 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6225 0x0000ffff /* end */
6227 static const float quad1[] =
6229 -1.0f, -1.0f, 0.1f,
6230 -1.0f, 0.0f, 0.1f,
6231 0.0f, -1.0f, 0.1f,
6232 0.0f, 0.0f, 0.1f,
6234 static const float quad2[] =
6236 0.0f, -1.0f, 0.1f,
6237 0.0f, 0.0f, 0.1f,
6238 1.0f, -1.0f, 0.1f,
6239 1.0f, 0.0f, 0.1f,
6241 static const float quad3[] =
6243 0.0f, 0.0f, 0.1f,
6244 0.0f, 1.0f, 0.1f,
6245 1.0f, 0.0f, 0.1f,
6246 1.0f, 1.0f, 0.1f,
6248 static const float quad4[] =
6250 -1.0f, 0.0f, 0.1f,
6251 -1.0f, 1.0f, 0.1f,
6252 0.0f, 0.0f, 0.1f,
6253 0.0f, 1.0f, 0.1f,
6255 static const float test_data_c1[4] = { 1.25f, -0.50f, -1.50f, 1.0f};
6256 static const float test_data_c2[4] = {-0.50f, 1.25f, 2.00f, 1.0f};
6258 window = create_window();
6259 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6260 ok(!!d3d, "Failed to create a D3D object.\n");
6261 if (!(device = create_device(d3d, window, window, TRUE)))
6263 skip("Failed to create a D3D device, skipping tests.\n");
6264 goto done;
6267 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6268 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6269 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
6271 skip("No ps_1_4 support, skipping tests.\n");
6272 IDirect3DDevice9_Release(device);
6273 goto done;
6276 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
6277 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6279 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
6280 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6281 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
6282 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6283 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
6284 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6285 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
6286 if(FAILED(hr)) shader_20 = NULL;
6288 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
6289 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6290 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
6291 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6292 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6293 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6295 hr = IDirect3DDevice9_BeginScene(device);
6296 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6298 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
6299 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6300 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
6301 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6303 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
6304 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6305 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
6306 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6308 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
6309 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6310 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
6311 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6313 if (shader_20)
6315 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
6316 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6317 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
6318 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6321 hr = IDirect3DDevice9_EndScene(device);
6322 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6324 color = getPixelColor(device, 160, 360);
6325 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
6326 "quad 1 has color %08x, expected 0x00808000\n", color);
6327 color = getPixelColor(device, 480, 360);
6328 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
6329 "quad 2 has color %08x, expected 0x00808000\n", color);
6330 color = getPixelColor(device, 480, 120);
6331 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
6332 "quad 3 has color %08x, expected 0x00808000\n", color);
6333 if(shader_20) {
6334 color = getPixelColor(device, 160, 120);
6335 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6336 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
6338 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6339 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6341 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
6342 IDirect3DPixelShader9_Release(shader_14);
6343 IDirect3DPixelShader9_Release(shader_12);
6344 IDirect3DPixelShader9_Release(shader_11);
6345 refcount = IDirect3DDevice9_Release(device);
6346 ok(!refcount, "Device has %u references left.\n", refcount);
6347 done:
6348 IDirect3D9_Release(d3d);
6349 DestroyWindow(window);
6352 static void dp2add_ps_test(void)
6354 IDirect3DPixelShader9 *shader_dp2add_sat;
6355 IDirect3DPixelShader9 *shader_dp2add;
6356 IDirect3DDevice9 *device;
6357 IDirect3D9 *d3d;
6358 ULONG refcount;
6359 D3DCAPS9 caps;
6360 DWORD color;
6361 HWND window;
6362 HRESULT hr;
6364 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
6365 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
6366 * source tokens can be constants. So, for this exercise, we move contents of c0 to
6367 * r0 first.
6368 * The result here for the r,g,b components should be roughly 0.5:
6369 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
6370 static const DWORD shader_code_dp2add[] = {
6371 0xffff0200, /* ps_2_0 */
6372 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
6374 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6375 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
6377 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
6378 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6379 0x0000ffff /* end */
6382 /* Test the _sat modifier, too. Result here should be:
6383 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
6384 * _SAT: ==> 1.0
6385 * ADD: (1.0 + -0.5) = 0.5
6387 static const DWORD shader_code_dp2add_sat[] = {
6388 0xffff0200, /* ps_2_0 */
6389 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
6391 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6392 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
6393 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
6395 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
6396 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6397 0x0000ffff /* end */
6399 static const float quad[] =
6401 -1.0f, -1.0f, 0.1f,
6402 -1.0f, 1.0f, 0.1f,
6403 1.0f, -1.0f, 0.1f,
6404 1.0f, 1.0f, 0.1f,
6407 window = create_window();
6408 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6409 ok(!!d3d, "Failed to create a D3D object.\n");
6410 if (!(device = create_device(d3d, window, window, TRUE)))
6412 skip("Failed to create a D3D device, skipping tests.\n");
6413 goto done;
6416 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6417 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6418 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
6420 skip("No ps_2_0 support, skipping tests.\n");
6421 IDirect3DDevice9_Release(device);
6422 goto done;
6425 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
6426 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6428 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
6429 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6431 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
6432 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6434 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6435 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6437 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
6438 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
6439 hr = IDirect3DDevice9_BeginScene(device);
6440 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6441 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
6442 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
6443 hr = IDirect3DDevice9_EndScene(device);
6444 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6446 color = getPixelColor(device, 360, 240);
6447 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1), "Got unexpected color 0x%08x.\n", color);
6449 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6450 ok(SUCCEEDED(hr), "Failed to present frame, hr %#x.\n", hr);
6451 IDirect3DPixelShader9_Release(shader_dp2add);
6453 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
6454 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
6455 hr = IDirect3DDevice9_BeginScene(device);
6456 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6457 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
6458 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
6459 hr = IDirect3DDevice9_EndScene(device);
6460 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6462 color = getPixelColor(device, 360, 240);
6463 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1), "Got unexpected color 0x%08x.\n", color);
6465 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6466 ok(SUCCEEDED(hr), "Failed to present frame, hr %#x.\n", hr);
6467 IDirect3DPixelShader9_Release(shader_dp2add_sat);
6469 refcount = IDirect3DDevice9_Release(device);
6470 ok(!refcount, "Device has %u references left.\n", refcount);
6471 done:
6472 IDirect3D9_Release(d3d);
6473 DestroyWindow(window);
6476 static void cnd_test(void)
6478 IDirect3DPixelShader9 *shader_11_coissue_2, *shader_12_coissue_2, *shader_13_coissue_2, *shader_14_coissue_2;
6479 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
6480 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
6481 IDirect3DDevice9 *device;
6482 IDirect3D9 *d3d;
6483 ULONG refcount;
6484 D3DCAPS9 caps;
6485 HWND window;
6486 DWORD color;
6487 HRESULT hr;
6489 /* ps 1.x shaders are rather picky with writemasks and source swizzles.
6490 * The dp3 is used to copy r0.r to all components of r1, then copy r1.a to
6491 * r0.a. Essentially it does a mov r0.a, r0.r, which isn't allowed as-is
6492 * in 1.x pixel shaders. */
6493 static const DWORD shader_code_11[] =
6495 0xffff0101, /* ps_1_1 */
6496 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6497 0x00000040, 0xb00f0000, /* texcoord t0 */
6498 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
6499 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
6500 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6501 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
6502 0x0000ffff /* end */
6504 static const DWORD shader_code_12[] =
6506 0xffff0102, /* ps_1_2 */
6507 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6508 0x00000040, 0xb00f0000, /* texcoord t0 */
6509 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6510 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
6511 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6512 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
6513 0x0000ffff /* end */
6515 static const DWORD shader_code_13[] =
6517 0xffff0103, /* ps_1_3 */
6518 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6519 0x00000040, 0xb00f0000, /* texcoord t0 */
6520 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6521 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
6522 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6523 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
6524 0x0000ffff /* end */
6526 static const DWORD shader_code_14[] =
6528 0xffff0104, /* ps_1_3 */
6529 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6530 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
6531 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
6532 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
6533 0x0000ffff /* end */
6536 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
6537 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
6538 * set by the compiler, it was added manually after compilation. Note that the COISSUE
6539 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
6540 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
6541 * well enough.
6543 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
6544 * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
6545 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
6546 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
6548 static const DWORD shader_code_11_coissue[] =
6550 0xffff0101, /* ps_1_1 */
6551 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6552 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6553 0x00000040, 0xb00f0000, /* texcoord t0 */
6554 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6555 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6556 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6557 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6558 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6559 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6560 0x0000ffff /* end */
6562 static const DWORD shader_code_11_coissue_2[] =
6564 0xffff0101, /* ps_1_1 */
6565 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6566 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6567 0x00000040, 0xb00f0000, /* texcoord t0 */
6568 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6569 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6570 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6571 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6572 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6573 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6574 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6575 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6576 0x0000ffff /* end */
6578 static const DWORD shader_code_12_coissue[] =
6580 0xffff0102, /* ps_1_2 */
6581 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6582 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6583 0x00000040, 0xb00f0000, /* texcoord t0 */
6584 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6585 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6586 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6587 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6588 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6589 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6590 0x0000ffff /* end */
6592 static const DWORD shader_code_12_coissue_2[] =
6594 0xffff0102, /* ps_1_2 */
6595 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6596 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6597 0x00000040, 0xb00f0000, /* texcoord t0 */
6598 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6599 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6600 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6601 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6602 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6603 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6604 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6605 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6606 0x0000ffff /* end */
6608 static const DWORD shader_code_13_coissue[] =
6610 0xffff0103, /* ps_1_3 */
6611 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6612 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6613 0x00000040, 0xb00f0000, /* texcoord t0 */
6614 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6615 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6616 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6617 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6618 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6619 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6620 0x0000ffff /* end */
6622 static const DWORD shader_code_13_coissue_2[] =
6624 0xffff0103, /* ps_1_3 */
6625 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6626 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6627 0x00000040, 0xb00f0000, /* texcoord t0 */
6628 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6629 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6630 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6631 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6632 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6633 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6634 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6635 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6636 0x0000ffff /* end */
6638 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1]
6639 * texcrd result to cnd, it will compare against 0.5. */
6640 static const DWORD shader_code_14_coissue[] =
6642 0xffff0104, /* ps_1_4 */
6643 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6644 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
6645 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
6646 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0, c1, c2 */
6647 0x0000ffff /* end */
6649 static const DWORD shader_code_14_coissue_2[] =
6651 0xffff0104, /* ps_1_4 */
6652 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6653 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
6654 0x00000001, 0x80080000, 0x80000000, /* mov r0.a, r0.x */
6655 0x00000001, 0x80070001, 0xa0ff0000, /* mov r1.xyz, c0.a */
6656 0x40000050, 0x80080001, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r1.a, r0.a, c1, c2 */
6657 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6658 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
6659 0x0000ffff /* end */
6661 static const float quad1[] =
6663 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6664 -1.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6665 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6666 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6668 static const float quad2[] =
6670 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6671 0.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6672 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6673 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6675 static const float quad3[] =
6677 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6678 0.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6679 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6680 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6682 static const float quad4[] =
6684 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6685 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6686 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6687 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6689 static const float test_data_c1[4] = {0.0f, 0.0f, 0.0f, 0.0f};
6690 static const float test_data_c2[4] = {1.0f, 1.0f, 1.0f, 1.0f};
6691 static const float test_data_c1_coi[4] = {0.0f, 1.0f, 0.0f, 0.0f};
6692 static const float test_data_c2_coi[4] = {1.0f, 0.0f, 1.0f, 1.0f};
6694 window = create_window();
6695 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6696 ok(!!d3d, "Failed to create a D3D object.\n");
6697 if (!(device = create_device(d3d, window, window, TRUE)))
6699 skip("Failed to create a D3D device, skipping tests.\n");
6700 goto done;
6703 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6704 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6705 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
6707 skip("No ps_1_4 support, skipping tests.\n");
6708 IDirect3DDevice9_Release(device);
6709 goto done;
6712 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
6713 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6715 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
6716 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6717 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
6718 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6719 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
6720 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6721 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
6722 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6723 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
6724 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6725 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
6726 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6727 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
6728 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6729 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
6730 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6731 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue_2, &shader_11_coissue_2);
6732 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6733 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue_2, &shader_12_coissue_2);
6734 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6735 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue_2, &shader_13_coissue_2);
6736 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6737 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue_2, &shader_14_coissue_2);
6738 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6740 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
6741 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6742 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
6743 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6744 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6745 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6747 hr = IDirect3DDevice9_BeginScene(device);
6748 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6750 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
6751 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6752 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6753 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6755 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
6756 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6757 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
6758 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6760 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
6761 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6762 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
6763 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6765 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
6766 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6767 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
6768 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6770 hr = IDirect3DDevice9_EndScene(device);
6771 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6773 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6774 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6776 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
6777 color = getPixelColor(device, 158, 118);
6778 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
6779 color = getPixelColor(device, 162, 118);
6780 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
6781 color = getPixelColor(device, 158, 122);
6782 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
6783 color = getPixelColor(device, 162, 122);
6784 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
6786 /* 1.1 shader. All 3 components get set, based on the .w comparison */
6787 color = getPixelColor(device, 158, 358);
6788 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
6789 color = getPixelColor(device, 162, 358);
6790 ok(color_match(color, 0x00000000, 1), "pixel 162, 358 has color 0x%08x, expected 0x00000000.\n", color);
6791 color = getPixelColor(device, 158, 362);
6792 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
6793 color = getPixelColor(device, 162, 362);
6794 ok(color_match(color, 0x00000000, 1), "pixel 162, 362 has color 0x%08x, expected 0x00000000.\n", color);
6796 /* 1.2 shader */
6797 color = getPixelColor(device, 478, 358);
6798 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
6799 color = getPixelColor(device, 482, 358);
6800 ok(color_match(color, 0x00000000, 1), "pixel 482, 358 has color 0x%08x, expected 0x00000000.\n", color);
6801 color = getPixelColor(device, 478, 362);
6802 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
6803 color = getPixelColor(device, 482, 362);
6804 ok(color_match(color, 0x00000000, 1), "pixel 482, 362 has color 0x%08x, expected 0x00000000.\n", color);
6806 /* 1.3 shader */
6807 color = getPixelColor(device, 478, 118);
6808 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
6809 color = getPixelColor(device, 482, 118);
6810 ok(color_match(color, 0x00000000, 1), "pixel 482, 118 has color 0x%08x, expected 0x00000000.\n", color);
6811 color = getPixelColor(device, 478, 122);
6812 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
6813 color = getPixelColor(device, 482, 122);
6814 ok(color_match(color, 0x00000000, 1), "pixel 482, 122 has color 0x%08x, expected 0x00000000.\n", color);
6816 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6817 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6819 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
6820 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6821 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
6822 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6823 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
6824 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6826 hr = IDirect3DDevice9_BeginScene(device);
6827 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6829 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
6830 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6831 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6832 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6834 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
6835 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6836 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
6837 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6839 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
6840 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6841 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
6842 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6844 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
6845 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6846 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
6847 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6849 hr = IDirect3DDevice9_EndScene(device);
6850 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6852 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6853 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6855 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
6856 * that we swapped the values in c1 and c2 to make the other tests return some color
6858 color = getPixelColor(device, 158, 118);
6859 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
6860 color = getPixelColor(device, 162, 118);
6861 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
6862 color = getPixelColor(device, 158, 122);
6863 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
6864 color = getPixelColor(device, 162, 122);
6865 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
6867 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
6868 * (The Win7 nvidia driver always selects c2)
6870 color = getPixelColor(device, 158, 358);
6871 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6872 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
6873 color = getPixelColor(device, 162, 358);
6874 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6875 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
6876 color = getPixelColor(device, 158, 362);
6877 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6878 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
6879 color = getPixelColor(device, 162, 362);
6880 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6881 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
6883 /* 1.2 shader */
6884 color = getPixelColor(device, 478, 358);
6885 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6886 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
6887 color = getPixelColor(device, 482, 358);
6888 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6889 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
6890 color = getPixelColor(device, 478, 362);
6891 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6892 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
6893 color = getPixelColor(device, 482, 362);
6894 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6895 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
6897 /* 1.3 shader */
6898 color = getPixelColor(device, 478, 118);
6899 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6900 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
6901 color = getPixelColor(device, 482, 118);
6902 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6903 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
6904 color = getPixelColor(device, 478, 122);
6905 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6906 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
6907 color = getPixelColor(device, 482, 122);
6908 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6909 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
6911 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6912 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6914 /* Retest with the coissue flag on the alpha instruction instead. This
6915 * works "as expected". The Windows 8 testbot (WARP) seems to handle this
6916 * the same as coissue on .rgb. */
6917 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
6918 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6920 hr = IDirect3DDevice9_BeginScene(device);
6921 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6923 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue_2);
6924 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6925 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6926 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6928 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue_2);
6929 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6930 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
6931 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6933 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue_2);
6934 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6935 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
6936 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6938 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue_2);
6939 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6940 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
6941 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6943 hr = IDirect3DDevice9_EndScene(device);
6944 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6946 /* 1.4 shader */
6947 color = getPixelColor(device, 158, 118);
6948 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
6949 color = getPixelColor(device, 162, 118);
6950 ok(color == 0x00000000, "pixel 162, 118 has color %08x, expected 0x00000000\n", color);
6951 color = getPixelColor(device, 158, 122);
6952 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
6953 color = getPixelColor(device, 162, 122);
6954 ok(color == 0x00000000, "pixel 162, 122 has color %08x, expected 0x00000000\n", color);
6956 /* 1.1 shader */
6957 color = getPixelColor(device, 238, 358);
6958 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6959 "pixel 238, 358 has color %08x, expected 0x00ffffff\n", color);
6960 color = getPixelColor(device, 242, 358);
6961 ok(color_match(color, 0x00000000, 1),
6962 "pixel 242, 358 has color %08x, expected 0x00000000\n", color);
6963 color = getPixelColor(device, 238, 362);
6964 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6965 "pixel 238, 362 has color %08x, expected 0x00ffffff\n", color);
6966 color = getPixelColor(device, 242, 362);
6967 ok(color_match(color, 0x00000000, 1),
6968 "pixel 242, 362 has color %08x, expected 0x00000000\n", color);
6970 /* 1.2 shader */
6971 color = getPixelColor(device, 558, 358);
6972 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6973 "pixel 558, 358 has color %08x, expected 0x00ffffff\n", color);
6974 color = getPixelColor(device, 562, 358);
6975 ok(color_match(color, 0x00000000, 1),
6976 "pixel 562, 358 has color %08x, expected 0x00000000\n", color);
6977 color = getPixelColor(device, 558, 362);
6978 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6979 "pixel 558, 362 has color %08x, expected 0x00ffffff\n", color);
6980 color = getPixelColor(device, 562, 362);
6981 ok(color_match(color, 0x00000000, 1),
6982 "pixel 562, 362 has color %08x, expected 0x00000000\n", color);
6984 /* 1.3 shader */
6985 color = getPixelColor(device, 558, 118);
6986 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6987 "pixel 558, 118 has color %08x, expected 0x00ffffff\n", color);
6988 color = getPixelColor(device, 562, 118);
6989 ok(color_match(color, 0x00000000, 1),
6990 "pixel 562, 118 has color %08x, expected 0x00000000\n", color);
6991 color = getPixelColor(device, 558, 122);
6992 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6993 "pixel 558, 122 has color %08x, expected 0x00ffffff\n", color);
6994 color = getPixelColor(device, 562, 122);
6995 ok(color_match(color, 0x00000000, 1),
6996 "pixel 562, 122 has color %08x, expected 0x00000000\n", color);
6998 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6999 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7001 IDirect3DPixelShader9_Release(shader_14_coissue_2);
7002 IDirect3DPixelShader9_Release(shader_13_coissue_2);
7003 IDirect3DPixelShader9_Release(shader_12_coissue_2);
7004 IDirect3DPixelShader9_Release(shader_11_coissue_2);
7005 IDirect3DPixelShader9_Release(shader_14_coissue);
7006 IDirect3DPixelShader9_Release(shader_13_coissue);
7007 IDirect3DPixelShader9_Release(shader_12_coissue);
7008 IDirect3DPixelShader9_Release(shader_11_coissue);
7009 IDirect3DPixelShader9_Release(shader_14);
7010 IDirect3DPixelShader9_Release(shader_13);
7011 IDirect3DPixelShader9_Release(shader_12);
7012 IDirect3DPixelShader9_Release(shader_11);
7013 refcount = IDirect3DDevice9_Release(device);
7014 ok(!refcount, "Device has %u references left.\n", refcount);
7015 done:
7016 IDirect3D9_Release(d3d);
7017 DestroyWindow(window);
7020 static void nested_loop_test(void)
7022 IDirect3DVertexShader9 *vshader;
7023 IDirect3DPixelShader9 *shader;
7024 IDirect3DDevice9 *device;
7025 IDirect3D9 *d3d;
7026 ULONG refcount;
7027 D3DCAPS9 caps;
7028 DWORD color;
7029 HWND window;
7030 HRESULT hr;
7032 static const DWORD shader_code[] =
7034 0xffff0300, /* ps_3_0 */
7035 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
7036 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
7037 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
7038 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7039 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
7040 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
7041 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
7042 0x0000001d, /* endloop */
7043 0x0000001d, /* endloop */
7044 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7045 0x0000ffff /* end */
7047 static const DWORD vshader_code[] =
7049 0xfffe0300, /* vs_3_0 */
7050 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7051 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7052 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7053 0x0000ffff /* end */
7055 static const float quad[] =
7057 -1.0f, -1.0f, 0.1f,
7058 -1.0f, 1.0f, 0.1f,
7059 1.0f, -1.0f, 0.1f,
7060 1.0f, 1.0f, 0.1f,
7063 window = create_window();
7064 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7065 ok(!!d3d, "Failed to create a D3D object.\n");
7066 if (!(device = create_device(d3d, window, window, TRUE)))
7068 skip("Failed to create a D3D device, skipping tests.\n");
7069 goto done;
7072 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7073 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7074 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
7076 skip("No shader model 3 support, skipping tests.\n");
7077 IDirect3DDevice9_Release(device);
7078 goto done;
7081 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7082 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
7083 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7084 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
7085 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
7086 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
7087 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
7088 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
7089 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7090 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
7091 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 1.0f, 0);
7092 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7094 hr = IDirect3DDevice9_BeginScene(device);
7095 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7096 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
7097 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7098 hr = IDirect3DDevice9_EndScene(device);
7099 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7101 color = getPixelColor(device, 360, 240);
7102 ok(color_match(color, 0x00800000, 1),
7103 "Nested loop test returned color 0x%08x, expected 0x00800000.\n", color);
7105 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7106 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7108 IDirect3DPixelShader9_Release(shader);
7109 IDirect3DVertexShader9_Release(vshader);
7110 refcount = IDirect3DDevice9_Release(device);
7111 ok(!refcount, "Device has %u references left.\n", refcount);
7112 done:
7113 IDirect3D9_Release(d3d);
7114 DestroyWindow(window);
7117 static void pretransformed_varying_test(void)
7119 /* dcl_position: fails to compile */
7120 static const DWORD blendweight_code[] =
7122 0xffff0300, /* ps_3_0 */
7123 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
7124 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7125 0x0000ffff /* end */
7127 static const DWORD blendindices_code[] =
7129 0xffff0300, /* ps_3_0 */
7130 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
7131 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7132 0x0000ffff /* end */
7134 static const DWORD normal_code[] =
7136 0xffff0300, /* ps_3_0 */
7137 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
7138 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7139 0x0000ffff /* end */
7141 /* psize: fails? */
7142 static const DWORD texcoord0_code[] =
7144 0xffff0300, /* ps_3_0 */
7145 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
7146 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7147 0x0000ffff /* end */
7149 static const DWORD tangent_code[] =
7151 0xffff0300, /* ps_3_0 */
7152 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
7153 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7154 0x0000ffff /* end */
7156 static const DWORD binormal_code[] =
7158 0xffff0300, /* ps_3_0 */
7159 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
7160 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7161 0x0000ffff /* end */
7163 /* tessfactor: fails */
7164 /* positiont: fails */
7165 static const DWORD color_code[] =
7167 0xffff0300, /* ps_3_0 */
7168 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
7169 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7170 0x0000ffff /* end */
7172 static const DWORD fog_code[] =
7174 0xffff0300, /* ps_3_0 */
7175 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
7176 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7177 0x0000ffff /* end */
7179 static const DWORD depth_code[] =
7181 0xffff0300, /* ps_3_0 */
7182 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
7183 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7184 0x0000ffff /* end */
7186 static const DWORD specular_code[] =
7188 0xffff0300, /* ps_3_0 */
7189 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
7190 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7191 0x0000ffff /* end */
7193 /* sample: fails */
7194 static const DWORD texcoord1_code[] =
7196 0xffff0300, /* ps_3_0 */
7197 0x0200001f, 0x80010005, 0x900f0000, /* dcl_texcoord1, v0 */
7198 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7199 0x0000ffff /* end */
7201 static const DWORD texcoord1_alpha_code[] =
7203 0xffff0300, /* ps_3_0 */
7204 0x0200001f, 0x80010005, 0x900f0000, /* dcl_texcoord1, v0 */
7205 0x02000001, 0x800f0800, 0x90ff0000, /* mov oC0, v0.w */
7206 0x0000ffff /* end */
7209 static const struct
7211 const char *name;
7212 const DWORD *shader_code;
7213 DWORD color;
7214 BOOL todo;
7215 BOOL broken;
7216 DWORD broken_color;
7218 tests[] =
7220 {"blendweight", blendweight_code, 0x00191919, TRUE },
7221 {"blendindices", blendindices_code, 0x00333333, TRUE },
7222 {"normal", normal_code, 0x004c4c4c, TRUE },
7223 {"texcoord0", texcoord0_code, 0x00808c8c, FALSE},
7224 {"tangent", tangent_code, 0x00999999, TRUE },
7225 {"binormal", binormal_code, 0x00b2b2b2, TRUE },
7226 {"color", color_code, 0x00e6e6e6, FALSE},
7227 {"fog", fog_code, 0x00666666, TRUE },
7228 {"depth", depth_code, 0x00cccccc, TRUE },
7229 {"specular", specular_code, 0x004488ff, FALSE},
7230 {"texcoord1", texcoord1_code, 0x00000000, FALSE},
7231 /* texcoord .w is 1.0 on r500 and WARP. See also test_uninitialized_varyings(). */
7232 {"texcoord1 alpha", texcoord1_alpha_code, 0x00000000, FALSE, TRUE, 0x00ffffff},
7234 /* Declare a monster vertex type :-) */
7235 static const D3DVERTEXELEMENT9 decl_elements[] = {
7236 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
7237 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
7238 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
7239 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
7240 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
7241 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7242 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
7243 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
7244 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
7245 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7246 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
7247 D3DDECL_END()
7250 static const struct
7252 float pos_x, pos_y, pos_z, rhw;
7253 float weight_1, weight_2, weight_3, weight_4;
7254 float index_1, index_2, index_3, index_4;
7255 float normal_1, normal_2, normal_3, normal_4;
7256 float fog_1, fog_2, fog_3, fog_4;
7257 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
7258 float tangent_1, tangent_2, tangent_3, tangent_4;
7259 float binormal_1, binormal_2, binormal_3, binormal_4;
7260 float depth_1, depth_2, depth_3, depth_4;
7261 D3DCOLOR diffuse;
7262 D3DCOLOR specular;
7264 data[] =
7267 0.0f, 0.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, 0.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 0.0f, 480.0f, 0.1f, 1.0f,
7294 0.1f, 0.1f, 0.1f, 0.1f,
7295 0.2f, 0.2f, 0.2f, 0.2f,
7296 0.3f, 0.3f, 0.3f, 0.3f,
7297 0.4f, 0.4f, 0.4f, 0.4f,
7298 0.5f, 0.55f, 0.55f, 0.55f,
7299 0.6f, 0.6f, 0.6f, 0.7f,
7300 0.7f, 0.7f, 0.7f, 0.6f,
7301 0.8f, 0.8f, 0.8f, 0.8f,
7302 0xe6e6e6e6, /* 0.9 * 256 */
7303 0x224488ff, /* Nothing special */
7306 640.0f, 480.0f, 0.1f, 1.0f,
7307 0.1f, 0.1f, 0.1f, 0.1f,
7308 0.2f, 0.2f, 0.2f, 0.2f,
7309 0.3f, 0.3f, 0.3f, 0.3f,
7310 0.4f, 0.4f, 0.4f, 0.4f,
7311 0.5f, 0.55f, 0.55f, 0.55f,
7312 0.6f, 0.6f, 0.6f, 0.7f,
7313 0.7f, 0.7f, 0.7f, 0.6f,
7314 0.8f, 0.8f, 0.8f, 0.8f,
7315 0xe6e6e6e6, /* 0.9 * 256 */
7316 0x224488ff, /* Nothing special */
7319 IDirect3DVertexDeclaration9 *decl;
7320 IDirect3DDevice9 *device;
7321 IDirect3D9 *d3d;
7322 unsigned int i;
7323 ULONG refcount;
7324 D3DCAPS9 caps;
7325 DWORD color;
7326 HWND window;
7327 HRESULT hr;
7329 window = create_window();
7330 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7331 ok(!!d3d, "Failed to create a D3D object.\n");
7332 if (!(device = create_device(d3d, window, window, TRUE)))
7334 skip("Failed to create a D3D device, skipping tests.\n");
7335 goto done;
7338 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7339 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7340 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
7342 skip("No shader model 3 support, skipping tests.\n");
7343 IDirect3DDevice9_Release(device);
7344 goto done;
7347 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
7348 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7349 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
7350 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
7352 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
7354 IDirect3DPixelShader9 *shader;
7356 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
7357 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7359 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &shader);
7360 ok(SUCCEEDED(hr), "Failed to create pixel shader for test %s, hr %#x.\n", tests[i].name, hr);
7362 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7363 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7365 hr = IDirect3DDevice9_BeginScene(device);
7366 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7367 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(*data));
7368 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7369 hr = IDirect3DDevice9_EndScene(device);
7370 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7372 /* This isn't a weekend's job to fix, ignore the problem for now.
7373 * Needs a replacement pipeline. */
7374 color = getPixelColor(device, 360, 240);
7375 if (tests[i].todo)
7376 todo_wine ok(color_match(color, tests[i].color, 1)
7377 || broken(color_match(color, 0x00000000, 1)
7378 && tests[i].shader_code == blendindices_code),
7379 "Test %s returned color 0x%08x, expected 0x%08x (todo).\n",
7380 tests[i].name, color, tests[i].color);
7381 else
7382 ok(color_match(color, tests[i].color, 1)
7383 || broken(color_match(color, tests[i].broken_color, 1) && tests[i].broken),
7384 "Test %s returned color 0x%08x, expected 0x%08x.\n",
7385 tests[i].name, color, tests[i].color);
7387 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7388 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7390 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7391 ok(SUCCEEDED(hr), "Failed to set pixel shader for test %s, hr %#x.\n", tests[i].name, hr);
7392 IDirect3DPixelShader9_Release(shader);
7395 IDirect3DVertexDeclaration9_Release(decl);
7396 refcount = IDirect3DDevice9_Release(device);
7397 ok(!refcount, "Device has %u references left.\n", refcount);
7398 done:
7399 IDirect3D9_Release(d3d);
7400 DestroyWindow(window);
7403 static void test_compare_instructions(void)
7405 IDirect3DVertexShader9 *shader_slt_scalar;
7406 IDirect3DVertexShader9 *shader_sge_scalar;
7407 IDirect3DVertexShader9 *shader_slt_vec;
7408 IDirect3DVertexShader9 *shader_sge_vec;
7409 IDirect3DDevice9 *device;
7410 IDirect3D9 *d3d;
7411 D3DCOLOR color;
7412 ULONG refcount;
7413 D3DCAPS9 caps;
7414 HWND window;
7415 HRESULT hr;
7417 static const DWORD shader_sge_vec_code[] =
7419 0xfffe0101, /* vs_1_1 */
7420 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7421 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7422 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7423 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
7424 0x0000ffff /* end */
7426 static const DWORD shader_slt_vec_code[] =
7428 0xfffe0101, /* vs_1_1 */
7429 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7430 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7431 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7432 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
7433 0x0000ffff /* end */
7435 static const DWORD shader_sge_scalar_code[] =
7437 0xfffe0101, /* vs_1_1 */
7438 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7439 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7440 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7441 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
7442 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
7443 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
7444 0x0000ffff /* end */
7446 static const DWORD shader_slt_scalar_code[] =
7448 0xfffe0101, /* vs_1_1 */
7449 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7450 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7451 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7452 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
7453 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
7454 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
7455 0x0000ffff /* end */
7457 static const float quad1[] =
7459 -1.0f, -1.0f, 0.1f,
7460 -1.0f, 0.0f, 0.1f,
7461 0.0f, -1.0f, 0.1f,
7462 0.0f, 0.0f, 0.1f,
7464 static const float quad2[] =
7466 0.0f, -1.0f, 0.1f,
7467 0.0f, 0.0f, 0.1f,
7468 1.0f, -1.0f, 0.1f,
7469 1.0f, 0.0f, 0.1f,
7471 static const float quad3[] =
7473 -1.0f, 0.0f, 0.1f,
7474 -1.0f, 1.0f, 0.1f,
7475 0.0f, 0.0f, 0.1f,
7476 0.0f, 1.0f, 0.1f,
7478 static const float quad4[] =
7480 0.0f, 0.0f, 0.1f,
7481 0.0f, 1.0f, 0.1f,
7482 1.0f, 0.0f, 0.1f,
7483 1.0f, 1.0f, 0.1f,
7485 static const float const0[4] = {0.8f, 0.2f, 0.2f, 0.2f};
7486 static const float const1[4] = {0.2f, 0.8f, 0.2f, 0.2f};
7488 window = create_window();
7489 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7490 ok(!!d3d, "Failed to create a D3D object.\n");
7491 if (!(device = create_device(d3d, window, window, TRUE)))
7493 skip("Failed to create a D3D device, skipping tests.\n");
7494 goto done;
7497 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7498 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7499 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
7501 skip("No vs_1_1 support, skipping tests.\n");
7502 IDirect3DDevice9_Release(device);
7503 goto done;
7506 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
7507 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
7509 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
7510 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7511 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
7512 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7513 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
7514 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7515 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
7516 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7517 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
7518 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
7519 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
7520 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
7521 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7522 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
7524 hr = IDirect3DDevice9_BeginScene(device);
7525 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7527 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
7528 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7529 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
7530 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7532 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
7533 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7534 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
7535 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7537 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
7538 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7539 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
7540 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7542 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
7543 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
7545 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
7546 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7547 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
7548 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7550 hr = IDirect3DDevice9_EndScene(device);
7551 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7553 color = getPixelColor(device, 160, 360);
7554 ok(color == 0x00ff00ff, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00ff00ff\n", color);
7555 color = getPixelColor(device, 480, 360);
7556 ok(color == 0x0000ff00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000ff00\n", color);
7557 color = getPixelColor(device, 160, 120);
7558 ok(color == 0x00ffffff, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00ffffff\n", color);
7559 color = getPixelColor(device, 480, 160);
7560 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
7562 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7563 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7565 IDirect3DVertexShader9_Release(shader_sge_vec);
7566 IDirect3DVertexShader9_Release(shader_slt_vec);
7567 IDirect3DVertexShader9_Release(shader_sge_scalar);
7568 IDirect3DVertexShader9_Release(shader_slt_scalar);
7569 refcount = IDirect3DDevice9_Release(device);
7570 ok(!refcount, "Device has %u references left.\n", refcount);
7571 done:
7572 IDirect3D9_Release(d3d);
7573 DestroyWindow(window);
7576 static void test_vshader_input(void)
7578 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
7579 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
7580 IDirect3DVertexDeclaration9 *decl_nocolor;
7581 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
7582 D3DADAPTER_IDENTIFIER9 identifier;
7583 IDirect3DPixelShader9 *ps;
7584 IDirect3DDevice9 *device;
7585 IDirect3D9 *d3d;
7586 ULONG refcount;
7587 unsigned int i;
7588 D3DCAPS9 caps;
7589 DWORD color;
7590 HWND window;
7591 HRESULT hr;
7592 BOOL warp;
7594 static const DWORD swapped_shader_code_3[] =
7596 0xfffe0300, /* vs_3_0 */
7597 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7598 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7599 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7600 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7601 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7602 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7603 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7604 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7605 0x0000ffff /* end */
7607 static const DWORD swapped_shader_code_1[] =
7609 0xfffe0101, /* vs_1_1 */
7610 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7611 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7612 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7613 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
7614 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7615 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7616 0x0000ffff /* end */
7618 static const DWORD swapped_shader_code_2[] =
7620 0xfffe0200, /* vs_2_0 */
7621 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7622 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7623 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7624 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
7625 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7626 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7627 0x0000ffff /* end */
7629 static const DWORD texcoord_color_shader_code_3[] =
7631 0xfffe0300, /* vs_3_0 */
7632 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7633 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7634 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7635 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7636 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7637 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
7638 0x0000ffff /* end */
7640 static const DWORD texcoord_color_shader_code_2[] =
7642 0xfffe0200, /* vs_2_0 */
7643 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7644 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7645 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7646 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
7647 0x0000ffff /* end */
7649 static const DWORD texcoord_color_shader_code_1[] =
7651 0xfffe0101, /* vs_1_1 */
7652 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7653 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7654 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7655 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
7656 0x0000ffff /* end */
7658 static const DWORD color_color_shader_code_3[] =
7660 0xfffe0300, /* vs_3_0 */
7661 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7662 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7663 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7664 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7665 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7666 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
7667 0x0000ffff /* end */
7669 static const DWORD color_color_shader_code_2[] =
7671 0xfffe0200, /* vs_2_0 */
7672 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7673 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7674 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7675 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
7676 0x0000ffff /* end */
7678 static const DWORD color_color_shader_code_1[] =
7680 0xfffe0101, /* vs_1_1 */
7681 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7682 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7683 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7684 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
7685 0x0000ffff /* end */
7687 static const DWORD ps3_code[] =
7689 0xffff0300, /* ps_3_0 */
7690 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
7691 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7692 0x0000ffff /* end */
7694 static const float quad1[] =
7696 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7697 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7698 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7699 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7701 static const float quad2[] =
7703 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7704 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7705 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7706 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7708 static const float quad3[] =
7710 -1.0f, 0.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f,
7711 -1.0f, 1.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
7712 0.0f, 0.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
7713 0.0f, 1.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
7715 static const float quad4[] =
7717 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7718 0.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7719 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7720 1.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7722 static const float quad1_modified[] =
7724 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
7725 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f,
7726 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
7727 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, -1.0f, -1.0f, 0.0f,
7729 static const float quad2_modified[] =
7731 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7732 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7733 1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7734 1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7736 static const struct
7738 struct vec3 position;
7739 DWORD diffuse;
7741 quad1_color[] =
7743 {{-1.0f, -1.0f, 0.1f}, 0x00ff8040},
7744 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
7745 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7746 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7748 quad2_color[] =
7750 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7751 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7752 {{ 1.0f, -1.0f, 0.1f}, 0x00ff8040},
7753 {{ 1.0f, 0.0f, 0.1f}, 0x00ff8040},
7755 quad3_color[] =
7757 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
7758 {{-1.0f, 1.0f, 0.1f}, 0x00ff8040},
7759 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7760 {{ 0.0f, 1.0f, 0.1f}, 0x00ff8040},
7762 static const float quad4_color[] =
7764 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7765 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7766 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7767 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7769 static const struct vec3 quad_nocolor[] =
7771 {-1.0f, -1.0f, 0.1f},
7772 {-1.0f, 1.0f, 0.1f},
7773 { 1.0f, -1.0f, 0.1f},
7774 { 1.0f, 1.0f, 0.1f},
7776 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] =
7778 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7779 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7780 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7781 D3DDECL_END()
7783 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] =
7785 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7786 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7787 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7788 D3DDECL_END()
7790 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] =
7792 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7793 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7794 D3DDECL_END()
7796 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] =
7798 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7799 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7800 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
7801 D3DDECL_END()
7803 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] =
7805 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7806 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7807 D3DDECL_END()
7809 static const D3DVERTEXELEMENT9 decl_elements_color_color[] =
7811 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7812 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7813 D3DDECL_END()
7815 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] =
7817 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7818 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7819 D3DDECL_END()
7821 static const D3DVERTEXELEMENT9 decl_elements_color_float[] =
7823 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7824 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7825 D3DDECL_END()
7827 static const D3DVERTEXELEMENT9 decl_elements_nocolor[] =
7829 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7830 D3DDECL_END()
7832 static const float normalize[4] = {1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f};
7833 static const float no_normalize[4] = {1.0f, 1.0f, 1.0f, 1.0f};
7835 window = create_window();
7836 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7837 ok(!!d3d, "Failed to create a D3D object.\n");
7838 if (!(device = create_device(d3d, window, window, TRUE)))
7840 skip("Failed to create a D3D device, skipping tests.\n");
7841 goto done;
7844 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7845 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7846 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
7848 skip("No vs_3_0 support, skipping tests.\n");
7849 IDirect3DDevice9_Release(device);
7850 goto done;
7852 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
7854 skip("No ps_3_0 support, skipping tests.\n");
7855 IDirect3DDevice9_Release(device);
7856 goto done;
7859 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
7860 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
7861 warp = adapter_is_warp(&identifier);
7863 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
7864 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7865 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
7866 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7867 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
7868 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7869 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
7870 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7872 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
7873 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7874 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
7875 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7876 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
7877 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7878 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
7879 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7880 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_nocolor, &decl_nocolor);
7881 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7883 hr = IDirect3DDevice9_CreatePixelShader(device, ps3_code, &ps);
7884 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
7886 for (i = 1; i <= 3; ++i)
7888 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
7889 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
7890 if(i == 3) {
7891 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
7892 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7893 hr = IDirect3DDevice9_SetPixelShader(device, ps);
7894 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7895 } else if(i == 2){
7896 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
7897 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7898 } else if(i == 1) {
7899 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
7900 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7903 hr = IDirect3DDevice9_BeginScene(device);
7904 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7906 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
7907 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7909 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
7910 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7911 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
7912 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7914 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
7915 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7916 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
7917 if (i == 3 || i == 2)
7918 ok(SUCCEEDED(hr), "Failed to draw, i %u, hr %#x.\n", i, hr);
7919 else if (i == 1)
7920 /* Succeeds or fails, depending on SW or HW vertex processing. */
7921 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
7923 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
7924 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7925 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
7926 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7928 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
7929 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7930 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
7931 if (i == 3 || i == 2)
7932 ok(SUCCEEDED(hr), "Failed to draw, i %u, hr %#x.\n", i, hr);
7933 else if (i == 1)
7934 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
7936 hr = IDirect3DDevice9_EndScene(device);
7937 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7939 if(i == 3 || i == 2) {
7940 color = getPixelColor(device, 160, 360);
7941 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
7942 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00ffff80\n", color);
7944 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
7945 color = getPixelColor(device, 480, 360);
7946 /* On the Windows 8 testbot (WARP) the draw succeeds, but uses
7947 * mostly random data as input. */
7948 ok(color == 0x00ffff00 || color == 0x00ff0000 || broken(warp),
7949 "Got unexpected color 0x%08x for quad 2 (1crd).\n", color);
7950 color = getPixelColor(device, 160, 120);
7951 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
7952 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
7953 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00ff0080\n", color);
7955 color = getPixelColor(device, 480, 160);
7956 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
7957 } else if(i == 1) {
7958 color = getPixelColor(device, 160, 360);
7959 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
7960 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00ffff80\n", color);
7961 color = getPixelColor(device, 480, 360);
7962 /* Accept the clear color as well in this case, since SW VP
7963 * returns an error. On the Windows 8 testbot (WARP) the draw
7964 * succeeds, but uses mostly random data as input. */
7965 ok(color == 0x00ffff00 || color == 0x00ff0000 || broken(warp),
7966 "Got unexpected color 0x%08x for quad 2 (1crd).\n", color);
7967 color = getPixelColor(device, 160, 120);
7968 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
7969 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00ff0080\n", color);
7970 color = getPixelColor(device, 480, 160);
7971 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
7974 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7975 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7977 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
7978 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7980 /* Now find out if the whole streams are re-read, or just the last
7981 * active value for the vertices is used. */
7982 hr = IDirect3DDevice9_BeginScene(device);
7983 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7985 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
7986 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7988 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
7989 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7990 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
7991 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7993 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
7994 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7995 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
7996 if (i == 3 || i == 2)
7997 ok(SUCCEEDED(hr), "Failed to draw, i %u, hr %#x.\n", i, hr);
7998 else if (i == 1)
7999 /* Succeeds or fails, depending on SW or HW vertex processing. */
8000 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
8002 hr = IDirect3DDevice9_EndScene(device);
8003 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8005 color = getPixelColor(device, 480, 350);
8006 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
8007 * as well.
8009 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
8010 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
8011 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
8012 * refrast's result.
8014 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
8016 ok(color == 0x000000ff || color == 0x00808080 || color == 0x00000000
8017 || broken(color_match(color, D3DCOLOR_ARGB(0x00, 0x0b, 0x75, 0x80), 1)),
8018 "Got unexpected color 0x%08x for quad 2 (different colors).\n", color);
8020 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8021 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8023 IDirect3DDevice9_SetVertexShader(device, NULL);
8024 IDirect3DDevice9_SetPixelShader(device, NULL);
8025 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8027 IDirect3DVertexShader9_Release(swapped_shader);
8030 for (i = 1; i <= 3; ++i)
8032 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
8033 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
8034 if(i == 3) {
8035 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
8036 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8037 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
8038 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8039 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8040 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
8041 } else if(i == 2){
8042 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
8043 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8044 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
8045 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8046 } else if(i == 1) {
8047 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
8048 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8049 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
8050 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8053 hr = IDirect3DDevice9_BeginScene(device);
8054 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8056 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
8057 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8058 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
8059 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8060 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
8061 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8063 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
8064 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8066 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
8067 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
8068 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
8069 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8070 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
8071 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8073 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
8074 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
8075 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
8076 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8077 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
8078 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8080 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
8081 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8082 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
8083 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8085 hr = IDirect3DDevice9_EndScene(device);
8086 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8088 color = getPixelColor(device, 160, 360);
8089 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
8090 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
8091 color = getPixelColor(device, 480, 360);
8092 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
8093 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
8094 color = getPixelColor(device, 160, 120);
8095 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
8096 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
8097 color = getPixelColor(device, 480, 160);
8098 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
8099 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00ffff00\n", color);
8101 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8102 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8104 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_nocolor);
8105 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8107 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
8108 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8110 hr = IDirect3DDevice9_BeginScene(device);
8111 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8112 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_nocolor, sizeof(quad_nocolor[0]));
8113 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8114 hr = IDirect3DDevice9_EndScene(device);
8115 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8117 /* WARP and r500 return a color from a previous draw. In case of WARP it is random, although most of the
8118 * time it is the color of the last draw, which happens to be the one with quad4_color above. AMD's r500
8119 * uses the last D3DCOLOR attribute, which is the one from quad3_color.
8121 * Newer AMD cards and Nvidia return zero. */
8122 color = getPixelColor(device, 160, 360);
8123 ok(color_match(color, 0x00000000, 1) || broken(color_match(color, 0x00ff8040, 1)) || broken(warp),
8124 "Got unexpected color 0x%08x for no color attribute test.\n", color);
8126 IDirect3DDevice9_SetVertexShader(device, NULL);
8127 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8128 IDirect3DDevice9_SetPixelShader(device, NULL);
8130 IDirect3DVertexShader9_Release(texcoord_color_shader);
8131 IDirect3DVertexShader9_Release(color_color_shader);
8134 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
8135 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
8136 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
8137 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
8139 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
8140 IDirect3DVertexDeclaration9_Release(decl_color_color);
8141 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
8142 IDirect3DVertexDeclaration9_Release(decl_color_float);
8143 IDirect3DVertexDeclaration9_Release(decl_nocolor);
8145 IDirect3DPixelShader9_Release(ps);
8146 refcount = IDirect3DDevice9_Release(device);
8147 ok(!refcount, "Device has %u references left.\n", refcount);
8148 done:
8149 IDirect3D9_Release(d3d);
8150 DestroyWindow(window);
8153 static void srgbtexture_test(void)
8155 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
8156 * texture stage state to render a quad using that texture. The resulting
8157 * color components should be 0x36 (~ 0.21), per this formula:
8158 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
8159 * This is true where srgb_color > 0.04045. */
8160 struct IDirect3DTexture9 *texture;
8161 struct IDirect3DSurface9 *surface;
8162 IDirect3DDevice9 *device;
8163 IDirect3D9 *d3d;
8164 D3DCOLOR color;
8165 ULONG refcount;
8166 HWND window;
8167 HRESULT hr;
8169 static const float quad[] =
8171 -1.0f, -1.0f, 0.0f, 0.0f, 1.0f,
8172 -1.0f, 1.0f, 0.0f, 0.0f, 0.0f,
8173 1.0f, -1.0f, 0.0f, 1.0f, 1.0f,
8174 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
8177 window = create_window();
8178 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8179 ok(!!d3d, "Failed to create a D3D object.\n");
8180 if (!(device = create_device(d3d, window, window, TRUE)))
8182 skip("Failed to create a D3D device, skipping tests.\n");
8183 goto done;
8186 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
8187 D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK)
8189 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported.\n");
8190 IDirect3DDevice9_Release(device);
8191 goto done;
8194 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
8195 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
8196 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8197 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
8199 fill_surface(surface, 0xff7f7f7f, 0);
8200 IDirect3DSurface9_Release(surface);
8202 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8203 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8204 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8205 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
8207 hr = IDirect3DDevice9_BeginScene(device);
8208 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8210 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
8211 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
8212 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8213 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8214 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
8215 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8217 hr = IDirect3DDevice9_EndScene(device);
8218 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8220 color = getPixelColor(device, 320, 240);
8221 ok(color_match(color, 0x00363636, 1), "sRGB quad has color 0x%08x, expected 0x00363636.\n", color);
8223 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8224 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8226 IDirect3DTexture9_Release(texture);
8227 refcount = IDirect3DDevice9_Release(device);
8228 ok(!refcount, "Device has %u references left.\n", refcount);
8229 done:
8230 IDirect3D9_Release(d3d);
8231 DestroyWindow(window);
8234 static void test_shademode(void)
8236 IDirect3DVertexBuffer9 *vb_strip;
8237 IDirect3DVertexBuffer9 *vb_list;
8238 IDirect3DVertexShader9 *vs;
8239 IDirect3DPixelShader9 *ps;
8240 IDirect3DDevice9 *device;
8241 DWORD color0, color1;
8242 void *data = NULL;
8243 IDirect3D9 *d3d;
8244 ULONG refcount;
8245 D3DCAPS9 caps;
8246 HWND window;
8247 HRESULT hr;
8248 UINT i;
8249 static const DWORD vs1_code[] =
8251 0xfffe0101, /* vs_1_1 */
8252 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8253 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
8254 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8255 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
8256 0x0000ffff
8258 static const DWORD vs2_code[] =
8260 0xfffe0200, /* vs_2_0 */
8261 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8262 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
8263 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8264 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
8265 0x0000ffff
8267 static const DWORD vs3_code[] =
8269 0xfffe0300, /* vs_3_0 */
8270 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8271 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
8272 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8273 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
8274 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8275 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
8276 0x0000ffff
8278 static const DWORD ps1_code[] =
8280 0xffff0101, /* ps_1_1 */
8281 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
8282 0x0000ffff
8284 static const DWORD ps2_code[] =
8286 0xffff0200, /* ps_2_0 */
8287 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
8288 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8289 0x0000ffff
8291 static const DWORD ps3_code[] =
8293 0xffff0300, /* ps_3_0 */
8294 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
8295 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8296 0x0000ffff
8298 static const struct
8300 struct vec3 position;
8301 DWORD diffuse;
8303 quad_strip[] =
8305 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
8306 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8307 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8308 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
8310 quad_list[] =
8312 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
8313 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8314 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8316 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8317 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8318 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
8320 static const struct test_shader
8322 DWORD version;
8323 const DWORD *code;
8325 novs = {0, NULL},
8326 vs_1 = {D3DVS_VERSION(1, 1), vs1_code},
8327 vs_2 = {D3DVS_VERSION(2, 0), vs2_code},
8328 vs_3 = {D3DVS_VERSION(3, 0), vs3_code},
8329 nops = {0, NULL},
8330 ps_1 = {D3DPS_VERSION(1, 1), ps1_code},
8331 ps_2 = {D3DPS_VERSION(2, 0), ps2_code},
8332 ps_3 = {D3DPS_VERSION(3, 0), ps3_code};
8333 static const struct
8335 const struct test_shader *vs, *ps;
8336 DWORD primtype;
8337 DWORD shademode;
8338 DWORD color0, color1;
8339 BOOL todo;
8341 tests[] =
8343 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8344 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_PHONG, 0x000dca28, 0x000d45c7, FALSE},
8345 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8346 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_PHONG, 0x000dca28, 0x000d45c7, FALSE},
8347 {&novs, &nops, D3DPT_TRIANGLELIST, D3DSHADE_FLAT, 0x00ff0000, 0x000000ff, FALSE},
8348 {&novs, &nops, D3DPT_TRIANGLELIST, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8349 {&vs_1, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8350 {&vs_1, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8351 {&vs_1, &ps_1, D3DPT_TRIANGLELIST, D3DSHADE_FLAT, 0x00ff0000, 0x000000ff, FALSE},
8352 {&vs_1, &ps_1, D3DPT_TRIANGLELIST, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8353 {&novs, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8354 {&vs_1, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8355 {&vs_2, &ps_2, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8356 {&vs_2, &ps_2, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8357 {&vs_3, &ps_3, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, TRUE},
8358 {&vs_3, &ps_3, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8361 window = create_window();
8362 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8363 ok(!!d3d, "Failed to create a D3D object.\n");
8364 if (!(device = create_device(d3d, window, window, TRUE)))
8366 skip("Failed to create a D3D device, skipping tests.\n");
8367 goto done;
8370 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8371 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8372 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
8373 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
8375 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8376 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
8378 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip), 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
8379 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8380 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
8381 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8382 memcpy(data, quad_strip, sizeof(quad_strip));
8383 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
8384 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
8386 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list), 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
8387 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8388 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
8389 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8390 memcpy(data, quad_list, sizeof(quad_list));
8391 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
8392 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
8394 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8395 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
8397 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
8398 * the color fixups we have to do for FLAT shading will be dependent on that. */
8400 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
8402 if (tests[i].vs->version)
8404 if (caps.VertexShaderVersion >= tests[i].vs->version)
8406 hr = IDirect3DDevice9_CreateVertexShader(device, tests[i].vs->code, &vs);
8407 ok(hr == D3D_OK, "Failed to create vertex shader, hr %#x.\n", hr);
8408 hr = IDirect3DDevice9_SetVertexShader(device, vs);
8409 ok(hr == D3D_OK, "Failed to set vertex shader, hr %#x.\n", hr);
8411 else
8413 skip("Shader version unsupported, skipping some tests.\n");
8414 continue;
8417 else
8419 vs = NULL;
8421 if (tests[i].ps->version)
8423 if (caps.PixelShaderVersion >= tests[i].ps->version)
8425 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].ps->code, &ps);
8426 ok(hr == D3D_OK, "Failed to create pixel shader, hr %#x.\n", hr);
8427 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8428 ok(hr == D3D_OK, "Failed to set pixel shader, hr %#x.\n", hr);
8430 else
8432 skip("Shader version unsupported, skipping some tests.\n");
8433 if (vs)
8435 IDirect3DDevice9_SetVertexShader(device, NULL);
8436 IDirect3DVertexShader9_Release(vs);
8438 continue;
8441 else
8443 ps = NULL;
8446 hr = IDirect3DDevice9_SetStreamSource(device, 0,
8447 tests[i].primtype == D3DPT_TRIANGLESTRIP ? vb_strip : vb_list, 0, sizeof(quad_strip[0]));
8448 ok(hr == D3D_OK, "Failed to set stream source, hr %#x.\n", hr);
8450 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
8451 ok(hr == D3D_OK, "Failed to clear, hr %#x.\n", hr);
8453 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shademode);
8454 ok(hr == D3D_OK, "Failed to set shade mode, hr %#x.\n", hr);
8456 hr = IDirect3DDevice9_BeginScene(device);
8457 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8458 hr = IDirect3DDevice9_DrawPrimitive(device, tests[i].primtype, 0, 2);
8459 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8460 hr = IDirect3DDevice9_EndScene(device);
8461 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8463 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
8464 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
8466 /* For D3DSHADE_FLAT it should take the color of the first vertex of
8467 * each triangle. This requires EXT_provoking_vertex or similar
8468 * functionality being available. */
8469 /* PHONG should be the same as GOURAUD, since no hardware implements
8470 * this. */
8471 todo_wine_if (tests[i].todo)
8473 ok(color_match(color0, tests[i].color0, 1), "Test %u shading has color0 %08x, expected %08x.\n",
8474 i, color0, tests[i].color0);
8475 ok(color_match(color1, tests[i].color1, 1), "Test %u shading has color1 %08x, expected %08x.\n",
8476 i, color1, tests[i].color1);
8478 IDirect3DDevice9_SetVertexShader(device, NULL);
8479 IDirect3DDevice9_SetPixelShader(device, NULL);
8481 if (ps)
8482 IDirect3DPixelShader9_Release(ps);
8483 if (vs)
8484 IDirect3DVertexShader9_Release(vs);
8487 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8488 ok(hr == D3D_OK, "Failed to present, hr %#x.\n", hr);
8490 IDirect3DVertexBuffer9_Release(vb_strip);
8491 IDirect3DVertexBuffer9_Release(vb_list);
8492 refcount = IDirect3DDevice9_Release(device);
8493 ok(!refcount, "Device has %u references left.\n", refcount);
8494 done:
8495 IDirect3D9_Release(d3d);
8496 DestroyWindow(window);
8499 static void test_blend(void)
8501 IDirect3DSurface9 *backbuffer, *offscreen;
8502 IDirect3DTexture9 *offscreenTexture;
8503 IDirect3DDevice9 *device;
8504 IDirect3D9 *d3d;
8505 D3DCOLOR color;
8506 ULONG refcount;
8507 HWND window;
8508 HRESULT hr;
8510 static const struct
8512 struct vec3 position;
8513 DWORD diffuse;
8515 quad1[] =
8517 {{-1.0f, -1.0f, 0.1f}, 0x4000ff00},
8518 {{-1.0f, 0.0f, 0.1f}, 0x4000ff00},
8519 {{ 1.0f, -1.0f, 0.1f}, 0x4000ff00},
8520 {{ 1.0f, 0.0f, 0.1f}, 0x4000ff00},
8522 quad2[] =
8524 {{-1.0f, 0.0f, 0.1f}, 0xc00000ff},
8525 {{-1.0f, 1.0f, 0.1f}, 0xc00000ff},
8526 {{ 1.0f, 0.0f, 0.1f}, 0xc00000ff},
8527 {{ 1.0f, 1.0f, 0.1f}, 0xc00000ff},
8529 static const float composite_quad[][5] =
8531 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
8532 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
8533 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
8534 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
8537 window = create_window();
8538 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8539 ok(!!d3d, "Failed to create a D3D object.\n");
8540 if (!(device = create_device(d3d, window, window, TRUE)))
8542 skip("Failed to create a D3D device, skipping tests.\n");
8543 goto done;
8546 /* Clear the render target with alpha = 0.5 */
8547 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x80ff0000, 1.0f, 0);
8548 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8550 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
8551 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8552 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
8554 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8555 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8557 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8558 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8560 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8561 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
8563 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8564 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8565 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8566 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8567 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8568 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8569 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8570 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8571 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8572 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8574 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8575 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8576 hr = IDirect3DDevice9_BeginScene(device);
8577 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8579 /* Draw two quads, one with src alpha blending, one with dest alpha
8580 * blending. */
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 /* Switch to the offscreen buffer, and redo the testing. The offscreen
8596 * render target doesn't have an alpha channel. DESTALPHA and INVDESTALPHA
8597 * "don't work" on render targets without alpha channel, they give
8598 * essentially ZERO and ONE blend factors. */
8599 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8600 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8601 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x80ff0000, 1.0f, 0);
8602 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8604 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8605 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8606 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8607 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8608 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8609 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8611 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
8612 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8613 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
8614 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8615 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8616 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8618 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8619 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8621 /* Render the offscreen texture onto the frame buffer to be able to
8622 * compare it regularly. Disable alpha blending for the final
8623 * composition. */
8624 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8625 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8626 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8627 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8629 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8630 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
8631 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
8632 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8634 hr = IDirect3DDevice9_EndScene(device);
8635 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8637 color = getPixelColor(device, 160, 360);
8638 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
8639 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
8641 color = getPixelColor(device, 160, 120);
8642 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
8643 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
8645 color = getPixelColor(device, 480, 360);
8646 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
8647 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
8649 color = getPixelColor(device, 480, 120);
8650 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
8651 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
8653 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8655 IDirect3DSurface9_Release(backbuffer);
8656 IDirect3DTexture9_Release(offscreenTexture);
8657 IDirect3DSurface9_Release(offscreen);
8658 refcount = IDirect3DDevice9_Release(device);
8659 ok(!refcount, "Device has %u references left.\n", refcount);
8660 done:
8661 IDirect3D9_Release(d3d);
8662 DestroyWindow(window);
8665 static void fixed_function_decl_test(void)
8667 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
8668 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_nocolor, *dcl_positiont;
8669 IDirect3DVertexBuffer9 *vb, *vb2;
8670 IDirect3DDevice9 *device;
8671 BOOL s_ok, ub_ok, f_ok;
8672 DWORD color, size, i;
8673 IDirect3D9 *d3d;
8674 ULONG refcount;
8675 D3DCAPS9 caps;
8676 HWND window;
8677 void *data;
8678 HRESULT hr;
8680 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
8681 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8682 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8683 D3DDECL_END()
8685 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
8686 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8687 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8688 D3DDECL_END()
8690 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
8691 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8692 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8693 D3DDECL_END()
8695 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
8696 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8697 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8698 D3DDECL_END()
8700 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
8701 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8702 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8703 D3DDECL_END()
8705 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
8706 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8707 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8708 D3DDECL_END()
8710 static const D3DVERTEXELEMENT9 decl_elements_nocolor[] = {
8711 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8712 D3DDECL_END()
8714 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
8715 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
8716 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8717 D3DDECL_END()
8719 static const struct
8721 struct vec3 position;
8722 DWORD diffuse;
8724 quad1[] = /* D3DCOLOR */
8726 {{-1.0f, -1.0f, 0.1f}, 0x00ffff00},
8727 {{-1.0f, 0.0f, 0.1f}, 0x00ffff00},
8728 {{ 0.0f, -1.0f, 0.1f}, 0x00ffff00},
8729 {{ 0.0f, 0.0f, 0.1f}, 0x00ffff00},
8731 quad2[] = /* UBYTE4N */
8733 {{-1.0f, 0.0f, 0.1f}, 0x00ffff00},
8734 {{-1.0f, 1.0f, 0.1f}, 0x00ffff00},
8735 {{ 0.0f, 0.0f, 0.1f}, 0x00ffff00},
8736 {{ 0.0f, 1.0f, 0.1f}, 0x00ffff00},
8738 static const struct
8740 struct vec3 position;
8741 struct { unsigned short x, y, z, w; } color;
8743 quad3[] = /* USHORT4N */
8745 {{0.0f, -1.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8746 {{0.0f, 0.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8747 {{1.0f, -1.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8748 {{1.0f, 0.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8750 static const struct
8752 struct vec3 position;
8753 struct vec4 color;
8755 quad4[] =
8757 {{0.0f, 0.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8758 {{0.0f, 1.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8759 {{1.0f, 0.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8760 {{1.0f, 1.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8762 static const DWORD colors[] =
8764 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8765 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8766 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8767 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8768 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8769 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8770 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8771 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8772 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8773 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8774 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8775 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8776 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8777 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8778 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8779 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8781 static const float quads[] =
8783 -1.0f, -1.0f, 0.1f,
8784 -1.0f, 0.0f, 0.1f,
8785 0.0f, -1.0f, 0.1f,
8786 0.0f, 0.0f, 0.1f,
8788 0.0f, -1.0f, 0.1f,
8789 0.0f, 0.0f, 0.1f,
8790 1.0f, -1.0f, 0.1f,
8791 1.0f, 0.0f, 0.1f,
8793 0.0f, 0.0f, 0.1f,
8794 0.0f, 1.0f, 0.1f,
8795 1.0f, 0.0f, 0.1f,
8796 1.0f, 1.0f, 0.1f,
8798 -1.0f, 0.0f, 0.1f,
8799 -1.0f, 1.0f, 0.1f,
8800 0.0f, 0.0f, 0.1f,
8801 0.0f, 1.0f, 0.1f,
8803 static const struct
8805 struct vec4 position;
8806 DWORD diffuse;
8808 quad_transformed[] =
8810 {{ 90.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
8811 {{570.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
8812 {{ 90.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
8813 {{570.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
8816 window = create_window();
8817 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8818 ok(!!d3d, "Failed to create a D3D object.\n");
8819 if (!(device = create_device(d3d, window, window, TRUE)))
8821 skip("Failed to create a D3D device, skipping tests.\n");
8822 goto done;
8825 memset(&caps, 0, sizeof(caps));
8826 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8827 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
8829 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
8830 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8832 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
8833 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8834 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
8835 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
8836 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
8837 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8838 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
8839 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
8840 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8841 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
8842 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8843 } else {
8844 trace("D3DDTCAPS_UBYTE4N not supported\n");
8845 dcl_ubyte_2 = NULL;
8846 dcl_ubyte = NULL;
8848 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
8849 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8850 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_nocolor, &dcl_nocolor);
8851 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8852 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
8853 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8855 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
8856 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
8857 0, 0, D3DPOOL_MANAGED, &vb, NULL);
8858 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8860 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8861 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
8863 hr = IDirect3DDevice9_BeginScene(device);
8864 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8866 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
8867 if (dcl_color)
8869 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
8870 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8871 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8872 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8875 /* Tests with non-standard fixed function types fail on the refrast. The
8876 * ATI driver partially accepts them, the NVIDIA driver accepts them all.
8877 * All those differences even though we're using software vertex
8878 * processing. Doh! */
8879 if (dcl_ubyte)
8881 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
8882 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8883 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8884 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8885 ub_ok = SUCCEEDED(hr);
8888 if (dcl_short)
8890 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
8891 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8892 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
8893 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8894 s_ok = SUCCEEDED(hr);
8897 if (dcl_float)
8899 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
8900 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8901 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
8902 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8903 f_ok = SUCCEEDED(hr);
8906 hr = IDirect3DDevice9_EndScene(device);
8907 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8909 if(dcl_short) {
8910 color = getPixelColor(device, 480, 360);
8911 ok(color == 0x000000ff || !s_ok,
8912 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
8914 if(dcl_ubyte) {
8915 color = getPixelColor(device, 160, 120);
8916 ok(color == 0x0000ffff || !ub_ok,
8917 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
8919 if(dcl_color) {
8920 color = getPixelColor(device, 160, 360);
8921 ok(color == 0x00ffff00,
8922 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
8924 if(dcl_float) {
8925 color = getPixelColor(device, 480, 120);
8926 ok(color == 0x00ff0000 || !f_ok,
8927 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
8929 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8931 /* The following test with vertex buffers doesn't serve to find out new
8932 * information from windows. It is a plain regression test because wined3d
8933 * uses different codepaths for attribute conversion with vertex buffers.
8934 * It makes sure that the vertex buffer one works, while the above tests
8935 * whether the immediate mode code works. */
8936 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
8937 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
8938 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8939 hr = IDirect3DDevice9_BeginScene(device);
8940 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8942 if (dcl_color)
8944 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
8945 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8946 memcpy(data, quad1, sizeof(quad1));
8947 hr = IDirect3DVertexBuffer9_Unlock(vb);
8948 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8949 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
8950 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8951 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
8952 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8953 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8954 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8957 if (dcl_ubyte)
8959 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
8960 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8961 memcpy(data, quad2, sizeof(quad2));
8962 hr = IDirect3DVertexBuffer9_Unlock(vb);
8963 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8964 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
8965 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8966 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
8967 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8968 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8969 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8970 ub_ok = SUCCEEDED(hr);
8973 if (dcl_short)
8975 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
8976 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8977 memcpy(data, quad3, sizeof(quad3));
8978 hr = IDirect3DVertexBuffer9_Unlock(vb);
8979 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8980 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
8981 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8982 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
8983 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8984 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8985 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8986 s_ok = SUCCEEDED(hr);
8989 if (dcl_float)
8991 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
8992 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8993 memcpy(data, quad4, sizeof(quad4));
8994 hr = IDirect3DVertexBuffer9_Unlock(vb);
8995 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8996 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
8997 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8998 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
8999 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
9000 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9001 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9002 f_ok = SUCCEEDED(hr);
9005 hr = IDirect3DDevice9_EndScene(device);
9006 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9008 if(dcl_short) {
9009 color = getPixelColor(device, 480, 360);
9010 ok(color == 0x000000ff || !s_ok,
9011 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
9013 if(dcl_ubyte) {
9014 color = getPixelColor(device, 160, 120);
9015 ok(color == 0x0000ffff || !ub_ok,
9016 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
9018 if(dcl_color) {
9019 color = getPixelColor(device, 160, 360);
9020 ok(color == 0x00ffff00,
9021 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
9023 if(dcl_float) {
9024 color = getPixelColor(device, 480, 120);
9025 ok(color == 0x00ff0000 || !f_ok,
9026 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
9028 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9030 /* Test with no diffuse color attribute. */
9031 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9032 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9034 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_nocolor);
9035 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9036 hr = IDirect3DDevice9_BeginScene(device);
9037 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9038 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quads, sizeof(float) * 3);
9039 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9040 hr = IDirect3DDevice9_EndScene(device);
9041 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9043 color = getPixelColor(device, 160, 360);
9044 ok(color == 0x00ffffff, "Got unexpected color 0x%08x in the no color attribute test.\n", color);
9046 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9048 /* Test what happens with specular lighting enabled and no specular color attribute. */
9049 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
9050 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
9051 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9052 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
9053 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#x.\n", hr);
9054 hr = IDirect3DDevice9_BeginScene(device);
9055 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9057 if (dcl_color)
9059 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
9060 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9061 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9062 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9064 if (dcl_ubyte)
9066 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
9067 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9068 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9069 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9070 ub_ok = SUCCEEDED(hr);
9072 if (dcl_short)
9074 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
9075 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9076 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
9077 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9078 s_ok = SUCCEEDED(hr);
9080 if (dcl_float)
9082 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
9083 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9084 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
9085 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9086 f_ok = SUCCEEDED(hr);
9089 hr = IDirect3DDevice9_EndScene(device);
9090 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9091 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARENABLE, FALSE);
9092 ok(SUCCEEDED(hr), "Failed to disable specular lighting, hr %#x.\n", hr);
9094 if (dcl_short)
9096 color = getPixelColor(device, 480, 360);
9097 ok(color == 0x000000ff || !s_ok,
9098 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff.\n", color);
9100 if (dcl_ubyte)
9102 color = getPixelColor(device, 160, 120);
9103 ok(color == 0x0000ffff || !ub_ok,
9104 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff.\n", color);
9106 if (dcl_color)
9108 color = getPixelColor(device, 160, 360);
9109 ok(color == 0x00ffff00,
9110 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00.\n", color);
9112 if (dcl_float)
9114 color = getPixelColor(device, 480, 120);
9115 ok(color == 0x00ff0000 || !f_ok,
9116 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000.\n", color);
9118 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9120 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
9121 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9122 memcpy(data, quad_transformed, sizeof(quad_transformed));
9123 hr = IDirect3DVertexBuffer9_Unlock(vb);
9124 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
9126 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
9127 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
9129 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9130 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9132 hr = IDirect3DDevice9_BeginScene(device);
9133 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9134 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
9135 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
9136 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9137 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9138 hr = IDirect3DDevice9_EndScene(device);
9139 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9141 color = getPixelColor(device, 88, 108);
9142 ok(color == 0x000000ff,
9143 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
9144 color = getPixelColor(device, 92, 108);
9145 ok(color == 0x000000ff,
9146 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
9147 color = getPixelColor(device, 88, 112);
9148 ok(color == 0x000000ff,
9149 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
9150 color = getPixelColor(device, 92, 112);
9151 ok(color == 0x00ffff00,
9152 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
9154 color = getPixelColor(device, 568, 108);
9155 ok(color == 0x000000ff,
9156 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
9157 color = getPixelColor(device, 572, 108);
9158 ok(color == 0x000000ff,
9159 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
9160 color = getPixelColor(device, 568, 112);
9161 ok(color == 0x00ffff00,
9162 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
9163 color = getPixelColor(device, 572, 112);
9164 ok(color == 0x000000ff,
9165 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
9167 color = getPixelColor(device, 88, 298);
9168 ok(color == 0x000000ff,
9169 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
9170 color = getPixelColor(device, 92, 298);
9171 ok(color == 0x00ffff00,
9172 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
9173 color = getPixelColor(device, 88, 302);
9174 ok(color == 0x000000ff,
9175 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
9176 color = getPixelColor(device, 92, 302);
9177 ok(color == 0x000000ff,
9178 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
9180 color = getPixelColor(device, 568, 298);
9181 ok(color == 0x00ffff00,
9182 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
9183 color = getPixelColor(device, 572, 298);
9184 ok(color == 0x000000ff,
9185 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
9186 color = getPixelColor(device, 568, 302);
9187 ok(color == 0x000000ff,
9188 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
9189 color = getPixelColor(device, 572, 302);
9190 ok(color == 0x000000ff,
9191 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
9193 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9195 /* This test is pointless without those two declarations: */
9196 if((!dcl_color_2) || (!dcl_ubyte_2)) {
9197 skip("color-ubyte switching test declarations aren't supported\n");
9198 goto out;
9201 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
9202 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9203 memcpy(data, quads, sizeof(quads));
9204 hr = IDirect3DVertexBuffer9_Unlock(vb);
9205 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
9206 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
9207 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9208 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9209 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
9210 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9211 memcpy(data, colors, sizeof(colors));
9212 hr = IDirect3DVertexBuffer9_Unlock(vb2);
9213 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
9215 for(i = 0; i < 2; i++) {
9216 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9217 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9219 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
9220 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
9221 if(i == 0) {
9222 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
9223 } else {
9224 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
9226 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
9228 hr = IDirect3DDevice9_BeginScene(device);
9229 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9231 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
9232 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9233 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9234 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9235 ub_ok = SUCCEEDED(hr);
9237 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
9238 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9239 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
9240 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9242 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
9243 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9244 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
9245 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9246 ub_ok = (SUCCEEDED(hr) && ub_ok);
9248 hr = IDirect3DDevice9_EndScene(device);
9249 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9251 if(i == 0) {
9252 color = getPixelColor(device, 480, 360);
9253 ok(color == 0x00ff0000,
9254 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
9255 color = getPixelColor(device, 160, 120);
9256 ok(color == 0x00ffffff,
9257 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
9258 color = getPixelColor(device, 160, 360);
9259 ok(color == 0x000000ff || !ub_ok,
9260 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
9261 color = getPixelColor(device, 480, 120);
9262 ok(color == 0x000000ff || !ub_ok,
9263 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
9264 } else {
9265 color = getPixelColor(device, 480, 360);
9266 ok(color == 0x000000ff,
9267 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
9268 color = getPixelColor(device, 160, 120);
9269 ok(color == 0x00ffffff,
9270 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
9271 color = getPixelColor(device, 160, 360);
9272 ok(color == 0x00ff0000 || !ub_ok,
9273 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
9274 color = getPixelColor(device, 480, 120);
9275 ok(color == 0x00ff0000 || !ub_ok,
9276 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
9278 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9281 IDirect3DVertexBuffer9_Release(vb2);
9282 out:
9283 IDirect3DVertexBuffer9_Release(vb);
9284 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
9285 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
9286 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
9287 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
9288 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
9289 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
9290 IDirect3DVertexDeclaration9_Release(dcl_nocolor);
9291 IDirect3DVertexDeclaration9_Release(dcl_positiont);
9292 refcount = IDirect3DDevice9_Release(device);
9293 ok(!refcount, "Device has %u references left.\n", refcount);
9294 done:
9295 IDirect3D9_Release(d3d);
9296 DestroyWindow(window);
9299 static void test_vshader_float16(void)
9301 IDirect3DVertexDeclaration9 *vdecl = NULL;
9302 IDirect3DVertexBuffer9 *buffer = NULL;
9303 IDirect3DVertexShader9 *shader;
9304 IDirect3DDevice9 *device;
9305 IDirect3D9 *d3d;
9306 ULONG refcount;
9307 D3DCAPS9 caps;
9308 DWORD color;
9309 HWND window;
9310 void *data;
9311 HRESULT hr;
9313 static const D3DVERTEXELEMENT9 decl_elements[] =
9315 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9316 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9317 D3DDECL_END()
9319 static const DWORD shader_code[] =
9321 0xfffe0101, /* vs_1_1 */
9322 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9323 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
9324 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
9325 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
9326 0x0000ffff,
9328 static const struct vertex_float16color
9330 float x, y, z;
9331 DWORD c1, c2;
9333 quad[] =
9335 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
9336 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
9337 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
9338 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
9340 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
9341 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
9342 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
9343 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
9345 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
9346 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
9347 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
9348 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
9350 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
9351 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
9352 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
9353 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
9356 window = create_window();
9357 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9358 ok(!!d3d, "Failed to create a D3D object.\n");
9359 if (!(device = create_device(d3d, window, window, TRUE)))
9361 skip("Failed to create a D3D device, skipping tests.\n");
9362 goto done;
9365 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9366 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
9367 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
9369 skip("No vs_3_0 support, skipping tests.\n");
9370 IDirect3DDevice9_Release(device);
9371 goto done;
9374 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff102030, 1.0f, 0);
9375 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9377 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
9378 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
9379 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9380 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9381 hr = IDirect3DDevice9_SetVertexShader(device, shader);
9382 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9384 hr = IDirect3DDevice9_BeginScene(device);
9385 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9386 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
9387 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9388 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
9389 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9390 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
9391 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9392 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
9393 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9394 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
9395 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9396 hr = IDirect3DDevice9_EndScene(device);
9397 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9399 color = getPixelColor(device, 480, 360);
9400 ok(color == 0x00ff0000,
9401 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
9402 color = getPixelColor(device, 160, 120);
9403 ok(color == 0x00000000,
9404 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
9405 color = getPixelColor(device, 160, 360);
9406 ok(color == 0x0000ff00,
9407 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
9408 color = getPixelColor(device, 480, 120);
9409 ok(color == 0x000000ff,
9410 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
9411 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9413 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
9414 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9416 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
9417 D3DPOOL_MANAGED, &buffer, NULL);
9418 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
9419 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
9420 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
9421 memcpy(data, quad, sizeof(quad));
9422 hr = IDirect3DVertexBuffer9_Unlock(buffer);
9423 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
9424 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
9425 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
9427 hr = IDirect3DDevice9_BeginScene(device);
9428 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9429 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9430 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9431 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
9432 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9433 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
9434 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9435 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
9436 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9437 hr = IDirect3DDevice9_EndScene(device);
9438 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9440 color = getPixelColor(device, 480, 360);
9441 ok(color == 0x00ff0000,
9442 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
9443 color = getPixelColor(device, 160, 120);
9444 ok(color == 0x00000000,
9445 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
9446 color = getPixelColor(device, 160, 360);
9447 ok(color == 0x0000ff00,
9448 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
9449 color = getPixelColor(device, 480, 120);
9450 ok(color == 0x000000ff,
9451 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
9452 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9454 IDirect3DVertexDeclaration9_Release(vdecl);
9455 IDirect3DVertexShader9_Release(shader);
9456 IDirect3DVertexBuffer9_Release(buffer);
9457 refcount = IDirect3DDevice9_Release(device);
9458 ok(!refcount, "Device has %u references left.\n", refcount);
9459 done:
9460 IDirect3D9_Release(d3d);
9461 DestroyWindow(window);
9464 static void conditional_np2_repeat_test(void)
9466 IDirect3DTexture9 *texture;
9467 IDirect3DDevice9 *device;
9468 D3DLOCKED_RECT rect;
9469 unsigned int x, y;
9470 DWORD *dst, color;
9471 IDirect3D9 *d3d;
9472 ULONG refcount;
9473 D3DCAPS9 caps;
9474 HWND window;
9475 HRESULT hr;
9477 static const float quad[] =
9479 -1.0f, -1.0f, 0.1f, -0.2f, -0.2f,
9480 -1.0f, 1.0f, 0.1f, -0.2f, 1.2f,
9481 1.0f, -1.0f, 0.1f, 1.2f, -0.2f,
9482 1.0f, 1.0f, 0.1f, 1.2f, 1.2f,
9485 window = create_window();
9486 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9487 ok(!!d3d, "Failed to create a D3D object.\n");
9488 if (!(device = create_device(d3d, window, window, TRUE)))
9490 skip("Failed to create a D3D device, skipping tests.\n");
9491 goto done;
9494 memset(&caps, 0, sizeof(caps));
9495 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9496 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
9497 if (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)
9499 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
9500 ok(caps.TextureCaps & D3DPTEXTURECAPS_POW2,
9501 "Card has conditional NP2 support without power of two restriction set\n");
9503 else if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
9505 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
9506 IDirect3DDevice9_Release(device);
9507 goto done;
9509 else
9511 skip("Card has unconditional NP2 support, skipping conditional NP2 tests\n");
9512 IDirect3DDevice9_Release(device);
9513 goto done;
9516 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
9517 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9519 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9520 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9522 memset(&rect, 0, sizeof(rect));
9523 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
9524 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9525 for(y = 0; y < 10; y++) {
9526 for(x = 0; x < 10; x++) {
9527 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
9528 if(x == 0 || x == 9 || y == 0 || y == 9) {
9529 *dst = 0x00ff0000;
9530 } else {
9531 *dst = 0x000000ff;
9535 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9536 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9538 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
9539 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9540 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9541 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
9542 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
9543 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
9544 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
9545 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
9546 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9547 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
9549 hr = IDirect3DDevice9_BeginScene(device);
9550 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9551 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9552 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9553 hr = IDirect3DDevice9_EndScene(device);
9554 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9556 color = getPixelColor(device, 1, 1);
9557 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
9558 color = getPixelColor(device, 639, 479);
9559 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
9561 color = getPixelColor(device, 135, 101);
9562 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
9563 color = getPixelColor(device, 140, 101);
9564 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
9565 color = getPixelColor(device, 135, 105);
9566 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
9567 color = getPixelColor(device, 140, 105);
9568 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
9570 color = getPixelColor(device, 135, 376);
9571 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
9572 color = getPixelColor(device, 140, 376);
9573 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
9574 color = getPixelColor(device, 135, 379);
9575 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
9576 color = getPixelColor(device, 140, 379);
9577 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
9579 color = getPixelColor(device, 500, 101);
9580 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
9581 color = getPixelColor(device, 504, 101);
9582 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
9583 color = getPixelColor(device, 500, 105);
9584 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
9585 color = getPixelColor(device, 504, 105);
9586 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
9588 color = getPixelColor(device, 500, 376);
9589 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
9590 color = getPixelColor(device, 504, 376);
9591 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
9592 color = getPixelColor(device, 500, 380);
9593 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
9594 color = getPixelColor(device, 504, 380);
9595 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
9597 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9599 IDirect3DTexture9_Release(texture);
9600 refcount = IDirect3DDevice9_Release(device);
9601 ok(!refcount, "Device has %u references left.\n", refcount);
9602 done:
9603 IDirect3D9_Release(d3d);
9604 DestroyWindow(window);
9607 static void vface_register_test(void)
9609 IDirect3DSurface9 *surface, *backbuffer;
9610 IDirect3DVertexShader9 *vshader;
9611 IDirect3DPixelShader9 *shader;
9612 IDirect3DTexture9 *texture;
9613 IDirect3DDevice9 *device;
9614 IDirect3D9 *d3d;
9615 ULONG refcount;
9616 D3DCAPS9 caps;
9617 DWORD color;
9618 HWND window;
9619 HRESULT hr;
9621 static const DWORD shader_code[] =
9623 0xffff0300, /* ps_3_0 */
9624 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9625 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
9626 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
9627 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
9628 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
9629 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
9630 0x0000ffff /* END */
9632 static const DWORD vshader_code[] =
9634 0xfffe0300, /* vs_3_0 */
9635 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9636 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
9637 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
9638 0x0000ffff /* end */
9640 static const float quad[] =
9642 -1.0f, -1.0f, 0.1f,
9643 1.0f, -1.0f, 0.1f,
9644 -1.0f, 0.0f, 0.1f,
9646 1.0f, -1.0f, 0.1f,
9647 1.0f, 0.0f, 0.1f,
9648 -1.0f, 0.0f, 0.1f,
9650 -1.0f, 0.0f, 0.1f,
9651 -1.0f, 1.0f, 0.1f,
9652 1.0f, 0.0f, 0.1f,
9654 1.0f, 0.0f, 0.1f,
9655 -1.0f, 1.0f, 0.1f,
9656 1.0f, 1.0f, 0.1f,
9658 static const float blit[] =
9660 0.0f, -1.0f, 0.1f, 0.0f, 0.0f,
9661 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
9662 0.0f, 1.0f, 0.1f, 0.0f, 1.0f,
9663 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
9666 window = create_window();
9667 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9668 ok(!!d3d, "Failed to create a D3D object.\n");
9669 if (!(device = create_device(d3d, window, window, TRUE)))
9671 skip("Failed to create a D3D device, skipping tests.\n");
9672 goto done;
9675 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9676 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
9677 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
9679 skip("No shader model 3 support, skipping tests.\n");
9680 IDirect3DDevice9_Release(device);
9681 goto done;
9684 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
9685 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9686 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
9687 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
9688 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
9689 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9690 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
9691 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
9692 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
9693 ok(SUCCEEDED(hr), "Failed to set cull mode, hr %#x.\n", hr);
9694 hr = IDirect3DDevice9_SetPixelShader(device, shader);
9695 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
9696 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
9697 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9698 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9699 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
9700 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9701 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
9703 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
9704 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9706 hr = IDirect3DDevice9_BeginScene(device);
9707 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9709 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
9710 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
9711 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
9712 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9713 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9714 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
9715 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9716 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9717 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
9718 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
9719 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9721 /* Blit the texture onto the back buffer to make it visible */
9722 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9723 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
9724 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9725 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9726 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
9727 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
9728 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9729 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
9730 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9731 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
9732 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9733 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9734 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
9735 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9737 hr = IDirect3DDevice9_EndScene(device);
9738 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9740 color = getPixelColor(device, 160, 360);
9741 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
9742 color = getPixelColor(device, 160, 120);
9743 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
9744 color = getPixelColor(device, 480, 360);
9745 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
9746 color = getPixelColor(device, 480, 120);
9747 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
9748 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9749 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
9751 IDirect3DPixelShader9_Release(shader);
9752 IDirect3DVertexShader9_Release(vshader);
9753 IDirect3DSurface9_Release(surface);
9754 IDirect3DSurface9_Release(backbuffer);
9755 IDirect3DTexture9_Release(texture);
9756 refcount = IDirect3DDevice9_Release(device);
9757 ok(!refcount, "Device has %u references left.\n", refcount);
9758 done:
9759 IDirect3D9_Release(d3d);
9760 DestroyWindow(window);
9763 static void fixed_function_bumpmap_test(void)
9765 IDirect3DVertexDeclaration9 *vertex_declaration;
9766 IDirect3DTexture9 *texture, *tex1, *tex2;
9767 D3DLOCKED_RECT locked_rect;
9768 IDirect3DDevice9 *device;
9769 BOOL L6V5U5_supported;
9770 float scale, offset;
9771 IDirect3D9 *d3d;
9772 unsigned int i;
9773 D3DCOLOR color;
9774 ULONG refcount;
9775 D3DCAPS9 caps;
9776 HWND window;
9777 HRESULT hr;
9779 static const float quad[][7] =
9781 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
9782 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
9783 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
9784 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
9786 static const D3DVERTEXELEMENT9 decl_elements[] =
9788 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9789 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9790 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
9791 D3DDECL_END()
9793 /* use asymmetric matrix to test loading */
9794 static const float bumpenvmat[4] = {0.0f, 0.5f, -0.5f, 0.0f};
9796 window = create_window();
9797 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9798 ok(!!d3d, "Failed to create a D3D object.\n");
9799 if (!(device = create_device(d3d, window, window, TRUE)))
9801 skip("Failed to create a D3D device, skipping tests.\n");
9802 goto done;
9805 memset(&caps, 0, sizeof(caps));
9806 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9807 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
9808 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP))
9810 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
9811 IDirect3DDevice9_Release(device);
9812 goto done;
9815 /* This check is disabled, some Windows drivers do not handle
9816 * D3DUSAGE_QUERY_LEGACYBUMPMAP properly. They report that it is not
9817 * supported, but after that bump mapping works properly. So just test if
9818 * the format is generally supported, and check the BUMPENVMAP flag. */
9819 L6V5U5_supported = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
9820 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_L6V5U5));
9821 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
9822 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_V8U8)))
9824 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
9825 IDirect3DDevice9_Release(device);
9826 return;
9829 /* Generate the textures */
9830 generate_bumpmap_textures(device);
9832 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
9833 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9834 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
9835 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9836 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
9837 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9838 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
9839 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9841 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
9842 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9843 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
9844 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9845 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
9846 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9848 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9849 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9850 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9851 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9852 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
9853 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9855 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9856 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9858 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9859 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
9861 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff00ff, 1.0f, 0);
9862 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
9864 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9865 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
9866 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9867 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
9869 hr = IDirect3DDevice9_BeginScene(device);
9870 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
9872 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9873 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
9875 hr = IDirect3DDevice9_EndScene(device);
9876 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
9878 color = getPixelColor(device, 240, 60);
9879 ok(color_match(color, 0x005ea000, 4), "Got unexpected color 0x%08x.\n", color);
9880 color = getPixelColor(device, 400, 60);
9881 ok(color_match(color, 0x009ea000, 4), "Got unexpected color 0x%08x.\n", color);
9882 color = getPixelColor(device, 80, 180);
9883 ok(color_match(color, 0x005ea000, 4), "Got unexpected color 0x%08x.\n", color);
9884 color = getPixelColor(device, 560, 180);
9885 ok(color_match(color, 0x009ea000, 4), "Got unexpected color 0x%08x.\n", color);
9886 color = getPixelColor(device, 80, 300);
9887 ok(color_match(color, 0x005e6000, 4), "Got unexpected color 0x%08x.\n", color);
9888 color = getPixelColor(device, 560, 300);
9889 ok(color_match(color, 0x009e6000, 4), "Got unexpected color 0x%08x.\n", color);
9890 color = getPixelColor(device, 240, 420);
9891 ok(color_match(color, 0x005e6000, 4), "Got unexpected color 0x%08x.\n", color);
9892 color = getPixelColor(device, 400, 420);
9893 ok(color_match(color, 0x009e6000, 4), "Got unexpected color 0x%08x.\n", color);
9894 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9895 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9897 for(i = 0; i < 2; i++) {
9898 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
9899 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
9900 IDirect3DTexture9_Release(texture); /* For the GetTexture */
9901 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
9902 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
9903 IDirect3DTexture9_Release(texture); /* To destroy it */
9906 if (!L6V5U5_supported || !(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE))
9908 skip("L6V5U5 / D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping tests.\n");
9909 IDirect3DVertexDeclaration9_Release(vertex_declaration);
9910 IDirect3DDevice9_Release(device);
9911 goto done;
9914 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9915 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
9916 /* This test only tests the luminance part. The bumpmapping part was already tested above and
9917 * would only make this test more complicated
9919 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
9920 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9921 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
9922 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9924 memset(&locked_rect, 0, sizeof(locked_rect));
9925 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
9926 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9927 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
9928 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
9929 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9931 memset(&locked_rect, 0, sizeof(locked_rect));
9932 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
9933 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9934 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
9935 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
9936 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9938 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9939 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
9940 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
9941 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
9943 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
9944 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9945 scale = 2.0;
9946 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
9947 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9948 offset = 0.1;
9949 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
9950 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9952 hr = IDirect3DDevice9_BeginScene(device);
9953 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9954 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9955 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9956 hr = IDirect3DDevice9_EndScene(device);
9957 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9959 color = getPixelColor(device, 320, 240);
9960 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
9961 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
9962 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
9964 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
9965 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9966 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9968 /* Check a result scale factor > 1.0 */
9969 scale = 10;
9970 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
9971 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9972 offset = 10;
9973 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
9974 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9976 hr = IDirect3DDevice9_BeginScene(device);
9977 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9978 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9979 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9980 hr = IDirect3DDevice9_EndScene(device);
9981 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9983 color = getPixelColor(device, 320, 240);
9984 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
9985 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9986 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9988 /* Check clamping in the scale factor calculation */
9989 scale = 1000;
9990 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
9991 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9992 offset = -1;
9993 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
9994 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9996 hr = IDirect3DDevice9_BeginScene(device);
9997 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9998 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9999 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10000 hr = IDirect3DDevice9_EndScene(device);
10001 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10003 color = getPixelColor(device, 320, 240);
10004 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
10005 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10006 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10008 IDirect3DTexture9_Release(tex1);
10009 IDirect3DTexture9_Release(tex2);
10010 IDirect3DVertexDeclaration9_Release(vertex_declaration);
10011 refcount = IDirect3DDevice9_Release(device);
10012 ok(!refcount, "Device has %u references left.\n", refcount);
10013 done:
10014 IDirect3D9_Release(d3d);
10015 DestroyWindow(window);
10018 static void stencil_cull_test(void)
10020 IDirect3DDevice9 *device;
10021 IDirect3D9 *d3d;
10022 ULONG refcount;
10023 D3DCAPS9 caps;
10024 HWND window;
10025 HRESULT hr;
10026 static const float quad1[] =
10028 -1.0, -1.0, 0.1,
10029 0.0, -1.0, 0.1,
10030 -1.0, 0.0, 0.1,
10031 0.0, 0.0, 0.1,
10033 static const float quad2[] =
10035 0.0, -1.0, 0.1,
10036 1.0, -1.0, 0.1,
10037 0.0, 0.0, 0.1,
10038 1.0, 0.0, 0.1,
10040 static const float quad3[] =
10042 0.0, 0.0, 0.1,
10043 1.0, 0.0, 0.1,
10044 0.0, 1.0, 0.1,
10045 1.0, 1.0, 0.1,
10047 static const float quad4[] =
10049 -1.0, 0.0, 0.1,
10050 0.0, 0.0, 0.1,
10051 -1.0, 1.0, 0.1,
10052 0.0, 1.0, 0.1,
10054 struct
10056 struct vec3 position;
10057 DWORD diffuse;
10059 painter[] =
10061 {{-1.0f, -1.0f, 0.0f}, 0x00000000},
10062 {{ 1.0f, -1.0f, 0.0f}, 0x00000000},
10063 {{-1.0f, 1.0f, 0.0f}, 0x00000000},
10064 {{ 1.0f, 1.0f, 0.0f}, 0x00000000},
10066 static const WORD indices_cw[] = {0, 1, 3};
10067 static const WORD indices_ccw[] = {0, 2, 3};
10068 unsigned int i;
10069 DWORD color;
10071 window = create_window();
10072 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10073 ok(!!d3d, "Failed to create a D3D object.\n");
10074 if (!(device = create_device(d3d, window, window, TRUE)))
10076 skip("Cannot create a device with a D24S8 stencil buffer.\n");
10077 DestroyWindow(window);
10078 IDirect3D9_Release(d3d);
10079 return;
10081 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10082 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
10083 if (!(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED))
10085 skip("No two sided stencil support\n");
10086 goto cleanup;
10089 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
10090 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10091 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10092 ok(SUCCEEDED(hr), "Failed to set FVF,hr %#x.\n", hr);
10094 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10095 ok(hr == D3D_OK, "Failed to disable Z test, %#x.\n", hr);
10096 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10097 ok(hr == D3D_OK, "Failed to disable lighting, %#x.\n", hr);
10098 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
10099 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10100 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
10101 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10102 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
10103 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10104 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
10105 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10107 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
10108 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10109 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
10110 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10111 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
10112 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10114 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
10115 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10116 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
10117 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10119 /* First pass: Fill the stencil buffer with some values... */
10120 hr = IDirect3DDevice9_BeginScene(device);
10121 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10123 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
10124 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10125 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10126 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
10127 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10128 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10129 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
10130 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10132 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
10133 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10134 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
10135 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10136 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10137 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
10138 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10139 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10140 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
10141 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10143 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
10144 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10145 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10146 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
10147 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10148 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10149 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
10150 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10152 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
10153 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10154 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10155 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
10156 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10157 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10158 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
10159 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10161 hr = IDirect3DDevice9_EndScene(device);
10162 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10164 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
10165 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10166 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
10167 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10168 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
10169 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10170 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
10171 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10172 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
10173 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10174 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
10175 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10177 /* 2nd pass: Make the stencil values visible */
10178 hr = IDirect3DDevice9_BeginScene(device);
10179 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10180 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10181 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
10182 for (i = 0; i < 16; ++i)
10184 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
10185 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10187 painter[0].diffuse = (i * 16); /* Creates shades of blue */
10188 painter[1].diffuse = (i * 16);
10189 painter[2].diffuse = (i * 16);
10190 painter[3].diffuse = (i * 16);
10191 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
10192 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10194 hr = IDirect3DDevice9_EndScene(device);
10195 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10197 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
10198 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10200 color = getPixelColor(device, 160, 420);
10201 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
10202 color = getPixelColor(device, 160, 300);
10203 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
10205 color = getPixelColor(device, 480, 420);
10206 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
10207 color = getPixelColor(device, 480, 300);
10208 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
10210 color = getPixelColor(device, 160, 180);
10211 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
10212 color = getPixelColor(device, 160, 60);
10213 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
10215 color = getPixelColor(device, 480, 180);
10216 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
10217 color = getPixelColor(device, 480, 60);
10218 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
10220 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10221 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10223 cleanup:
10224 refcount = IDirect3DDevice9_Release(device);
10225 ok(!refcount, "Device has %u references left.\n", refcount);
10226 IDirect3D9_Release(d3d);
10227 DestroyWindow(window);
10230 static void test_fragment_coords(void)
10232 IDirect3DSurface9 *surface = NULL, *backbuffer;
10233 IDirect3DPixelShader9 *shader, *shader_frac;
10234 IDirect3DVertexShader9 *vshader;
10235 IDirect3DDevice9 *device;
10236 D3DLOCKED_RECT lr;
10237 IDirect3D9 *d3d;
10238 ULONG refcount;
10239 D3DCAPS9 caps;
10240 DWORD color;
10241 HWND window;
10242 HRESULT hr;
10243 DWORD *pos;
10245 static const DWORD shader_code[] =
10247 0xffff0300, /* ps_3_0 */
10248 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
10249 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
10250 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
10251 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
10252 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
10253 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
10254 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
10255 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
10256 0x0000ffff /* end */
10258 static const DWORD shader_frac_code[] =
10260 0xffff0300, /* ps_3_0 */
10261 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
10262 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
10263 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
10264 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
10265 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
10266 0x0000ffff /* end */
10268 static const DWORD vshader_code[] =
10270 0xfffe0300, /* vs_3_0 */
10271 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10272 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
10273 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
10274 0x0000ffff /* end */
10276 static const float quad[] =
10278 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
10279 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
10280 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
10281 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
10283 float constant[4] = {1.0, 0.0, 320, 240};
10285 window = create_window();
10286 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10287 ok(!!d3d, "Failed to create a D3D object.\n");
10288 if (!(device = create_device(d3d, window, window, TRUE)))
10290 skip("Failed to create a D3D device, skipping tests.\n");
10291 goto done;
10294 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10295 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
10296 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
10298 skip("No shader model 3 support, skipping tests.\n");
10299 IDirect3DDevice9_Release(device);
10300 goto done;
10303 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10304 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
10305 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
10306 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
10307 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
10308 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
10309 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
10310 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
10311 hr = IDirect3DDevice9_SetPixelShader(device, shader);
10312 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
10313 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
10314 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
10315 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10316 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
10317 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
10318 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
10320 hr = IDirect3DDevice9_BeginScene(device);
10321 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10322 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
10323 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
10324 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
10325 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10326 hr = IDirect3DDevice9_EndScene(device);
10327 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10329 /* This has to be pixel exact */
10330 color = getPixelColor(device, 319, 239);
10331 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
10332 color = getPixelColor(device, 320, 239);
10333 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
10334 color = getPixelColor(device, 319, 240);
10335 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
10336 color = getPixelColor(device, 320, 240);
10337 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
10338 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10340 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
10341 &surface, NULL);
10342 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
10343 hr = IDirect3DDevice9_BeginScene(device);
10344 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10345 constant[2] = 16; constant[3] = 16;
10346 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
10347 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
10348 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
10349 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10350 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
10351 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10352 hr = IDirect3DDevice9_EndScene(device);
10353 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10355 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
10356 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
10358 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
10359 color = *pos & 0x00ffffff;
10360 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
10361 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
10362 color = *pos & 0x00ffffff;
10363 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
10364 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
10365 color = *pos & 0x00ffffff;
10366 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
10367 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
10368 color = *pos & 0x00ffffff;
10369 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
10371 hr = IDirect3DSurface9_UnlockRect(surface);
10372 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
10374 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
10375 * have full control over the multisampling setting inside this test
10377 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
10378 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
10379 hr = IDirect3DDevice9_BeginScene(device);
10380 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10381 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
10382 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
10383 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
10384 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10385 hr = IDirect3DDevice9_EndScene(device);
10386 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10388 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10389 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
10391 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
10392 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
10394 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
10395 color = *pos & 0x00ffffff;
10396 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
10398 hr = IDirect3DSurface9_UnlockRect(surface);
10399 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
10401 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
10402 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
10403 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10404 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
10405 IDirect3DPixelShader9_Release(shader);
10406 IDirect3DPixelShader9_Release(shader_frac);
10407 IDirect3DVertexShader9_Release(vshader);
10408 if(surface) IDirect3DSurface9_Release(surface);
10409 IDirect3DSurface9_Release(backbuffer);
10410 refcount = IDirect3DDevice9_Release(device);
10411 ok(!refcount, "Device has %u references left.\n", refcount);
10412 done:
10413 IDirect3D9_Release(d3d);
10414 DestroyWindow(window);
10417 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
10419 D3DCOLOR color;
10421 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
10422 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
10423 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
10424 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
10425 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
10427 ++r;
10428 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
10429 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
10430 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
10431 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
10432 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
10434 return TRUE;
10437 static void test_pointsize(void)
10439 static const float a = 1.0f, b = 1.0f, c = 1.0f;
10440 float ptsize, ptsizemax_orig, ptsizemin_orig;
10441 IDirect3DSurface9 *rt, *backbuffer;
10442 IDirect3DTexture9 *tex1, *tex2;
10443 IDirect3DDevice9 *device;
10444 IDirect3DVertexShader9 *vs;
10445 IDirect3DPixelShader9 *ps;
10446 D3DLOCKED_RECT lr;
10447 IDirect3D9 *d3d;
10448 D3DCOLOR color;
10449 ULONG refcount;
10450 D3DCAPS9 caps;
10451 HWND window;
10452 HRESULT hr;
10453 unsigned int i, j;
10455 static const RECT rect = {0, 0, 128, 128};
10456 static const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000, 0x00000000, 0x00000000};
10457 static const DWORD tex2_data[4] = {0x00000000, 0x0000ff00, 0x00000000, 0x0000ff00};
10458 static const float vertices[] =
10460 64.0f, 64.0f, 0.1f,
10461 128.0f, 64.0f, 0.1f,
10462 192.0f, 64.0f, 0.1f,
10463 256.0f, 64.0f, 0.1f,
10464 320.0f, 64.0f, 0.1f,
10465 384.0f, 64.0f, 0.1f,
10466 448.0f, 64.0f, 0.1f,
10467 512.0f, 64.0f, 0.1f,
10469 static const struct
10471 float x, y, z;
10472 float point_size;
10474 vertex_pointsize = {64.0f, 64.0f, 0.1f, 48.0f},
10475 vertex_pointsize_scaled = {64.0f, 64.0f, 0.1f, 24.0f},
10476 vertex_pointsize_zero = {64.0f, 64.0f, 0.1f, 0.0f};
10477 /* Writing a texture coordinate from the shader is technically unnecessary, but is required
10478 * to make Windows AMD r500 drivers work. Without it, texture coordinates in the pixel
10479 * shaders are 0. */
10480 static const DWORD vshader_code[] =
10482 0xfffe0101, /* vs_1_1 */
10483 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10484 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10485 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10486 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10487 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
10488 0x00000001, 0xe00f0000, 0x90e40000, /* mov oT0, v0 */
10489 0x00000001, 0xe00f0001, 0x90e40000, /* mov oT1, v0 */
10490 0x0000ffff
10492 static const DWORD vshader_psize_code[] =
10494 0xfffe0101, /* vs_1_1 */
10495 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10496 0x0000001f, 0x80000004, 0x900f0001, /* dcl_psize v1 */
10497 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10498 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10499 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10500 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
10501 0x00000001, 0xc00f0002, 0x90000001, /* mov oPts, v1.x */
10502 0x00000001, 0xe00f0000, 0x90e40000, /* mov oT0, v0 */
10503 0x00000001, 0xe00f0001, 0x90e40000, /* mov oT1, v0 */
10504 0x0000ffff
10506 static const DWORD pshader_code[] =
10508 0xffff0101, /* ps_1_1 */
10509 0x00000042, 0xb00f0000, /* tex t0 */
10510 0x00000042, 0xb00f0001, /* tex t1 */
10511 0x00000002, 0x800f0000, 0xb0e40000, 0xb0e40001, /* add r0, t0, t1 */
10512 0x0000ffff
10514 static const DWORD pshader2_code[] =
10516 0xffff0200, /* ps_2_0 */
10517 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
10518 0x0200001f, 0x80000000, 0xb00f0001, /* dcl t1 */
10519 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10520 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10521 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
10522 0x03000042, 0x800f0001, 0xb0e40001, 0xa0e40801, /* texld r1, t1, s1 */
10523 0x03000002, 0x800f0000, 0x80e40000, 0x80e40001, /* add r0, r0, r1 */
10524 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
10525 0x0000ffff
10527 static const DWORD pshader2_zw_code[] =
10529 0xffff0200, /* ps_2_0 */
10530 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
10531 0x0200001f, 0x80000000, 0xb00f0001, /* dcl t1 */
10532 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10533 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10534 0x02000001, 0x80030000, 0xb01b0000, /* mov r0.xy, t0.wzyx */
10535 0x02000001, 0x80030001, 0xb01b0001, /* mov r1.xy, t1.wzyx */
10536 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, /* texld r0, r0, s0 */
10537 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40801, /* texld r1, r1, s1 */
10538 0x03000002, 0x800f0000, 0x80e40000, 0x80e40001, /* add r0, r0, r1 */
10539 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
10540 0x0000ffff
10542 static const DWORD vshader3_code[] =
10544 0xfffe0300, /* vs_3_0 */
10545 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10546 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
10547 0x0200001f, 0x80000005, 0xe00f0001, /* dcl_texcoord0 o1 */
10548 0x0200001f, 0x80010005, 0xe00f0002, /* dcl_texcoord1 o2 */
10549 0x03000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10550 0x04000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10551 0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10552 0x04000004, 0xe00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad o0, v0.w, c3, r0 */
10553 0x02000001, 0xe00f0001, 0x90000000, /* mov o1, v0.x */
10554 0x02000001, 0xe00f0002, 0x90000000, /* mov o2, v0.x */
10555 0x0000ffff
10557 static const DWORD vshader3_psize_code[] =
10559 0xfffe0300, /* vs_3_0 */
10560 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10561 0x0200001f, 0x80000004, 0x90010001, /* dcl_psize v1.x */
10562 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
10563 0x0200001f, 0x80000004, 0xe00f0001, /* dcl_psize o1 */
10564 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
10565 0x0200001f, 0x80010005, 0xe00f0003, /* dcl_texcoord1 o3 */
10566 0x03000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10567 0x04000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10568 0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10569 0x04000004, 0xe00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad o0, v0.w, c3, r0 */
10570 0x02000001, 0xe00f0001, 0x90000001, /* mov o1, v1.x */
10571 0x02000001, 0xe00f0002, 0x90000000, /* mov o2, v0.x */
10572 0x02000001, 0xe00f0003, 0x90000000, /* mov o3, v0.x */
10573 0x0000ffff
10575 static const DWORD pshader3_code[] =
10577 0xffff0300, /* ps_3_0 */
10578 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
10579 0x0200001f, 0x80010005, 0x900f0001, /* dcl_texcoord1 v1 */
10580 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10581 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10582 0x03000042, 0x800f0000, 0x90e40000, 0xa0e40800, /* texld r0, v0, s0 */
10583 0x03000042, 0x800f0001, 0x90e40001, 0xa0e40801, /* texld r1, v1, s1 */
10584 0x03000002, 0x800f0800, 0x80e40000, 0x80e40001, /* add oC0, r0, r1 */
10585 0x0000ffff
10587 static const DWORD pshader3_zw_code[] =
10589 0xffff0300, /* ps_3_0 */
10590 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
10591 0x0200001f, 0x80010005, 0x900f0001, /* dcl_texcoord1 v1 */
10592 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10593 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10594 0x03000042, 0x800f0000, 0x90fe0000, 0xa0e40800, /* texld r0, v0.zw, s0 */
10595 0x03000042, 0x800f0001, 0x90fe0001, 0xa0e40801, /* texld r1, v1.zw, s1 */
10596 0x03000002, 0x800f0800, 0x80e40000, 0x80e40001, /* add oC0, r0, r1 */
10597 0x0000ffff
10599 static const struct test_shader
10601 DWORD version;
10602 const DWORD *code;
10604 novs = {0, NULL},
10605 vs1 = {D3DVS_VERSION(1, 1), vshader_code},
10606 vs1_psize = {D3DVS_VERSION(1, 1), vshader_psize_code},
10607 vs3 = {D3DVS_VERSION(3, 0), vshader3_code},
10608 vs3_psize = {D3DVS_VERSION(3, 0), vshader3_psize_code},
10609 nops = {0, NULL},
10610 ps1 = {D3DPS_VERSION(1, 1), pshader_code},
10611 ps2 = {D3DPS_VERSION(2, 0), pshader2_code},
10612 ps2_zw = {D3DPS_VERSION(2, 0), pshader2_zw_code},
10613 ps3 = {D3DPS_VERSION(3, 0), pshader3_code},
10614 ps3_zw = {D3DPS_VERSION(3, 0), pshader3_zw_code};
10615 static const struct
10617 const struct test_shader *vs;
10618 const struct test_shader *ps;
10619 DWORD accepted_fvf;
10620 unsigned int nonscaled_size, scaled_size;
10621 BOOL gives_0_0_texcoord;
10622 BOOL allow_broken;
10624 test_setups[] =
10626 {&novs, &nops, D3DFVF_XYZ, 32, 45, FALSE, FALSE},
10627 {&vs1, &ps1, D3DFVF_XYZ, 32, 32, FALSE, FALSE},
10628 {&novs, &ps1, D3DFVF_XYZ, 32, 45, FALSE, FALSE},
10629 {&vs1, &nops, D3DFVF_XYZ, 32, 32, FALSE, FALSE},
10630 {&novs, &ps2, D3DFVF_XYZ, 32, 45, FALSE, TRUE},
10631 {&novs, &ps2_zw, D3DFVF_XYZ, 32, 45, TRUE, FALSE},
10632 {&vs1, &ps2, D3DFVF_XYZ, 32, 32, FALSE, TRUE},
10633 {&vs1, &ps2_zw, D3DFVF_XYZ, 32, 32, TRUE, FALSE},
10634 {&vs3, &ps3, D3DFVF_XYZ, 32, 32, FALSE, TRUE},
10635 {&vs3, &ps3_zw, D3DFVF_XYZ, 32, 32, TRUE, FALSE},
10636 {&novs, &nops, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 33, FALSE, FALSE},
10637 {&vs1_psize, &ps1, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 24, FALSE, FALSE},
10638 {&vs3_psize, &ps3, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 24, FALSE, TRUE},
10640 static const struct
10642 BOOL zero_size;
10643 BOOL scale;
10644 BOOL override_min;
10645 DWORD fvf;
10646 const void *vertex_data;
10647 unsigned int vertex_size;
10649 tests[] =
10651 {FALSE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10652 {FALSE, TRUE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10653 {FALSE, FALSE, TRUE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10654 {TRUE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10655 {FALSE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
10656 {FALSE, TRUE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_scaled, sizeof(vertex_pointsize_scaled)},
10657 {FALSE, FALSE, TRUE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
10658 {TRUE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_zero, sizeof(vertex_pointsize_zero)},
10660 /* Transforms the coordinate system [-1.0;1.0]x[1.0;-1.0] to
10661 * [0.0;0.0]x[640.0;480.0]. Z is untouched. */
10662 D3DMATRIX matrix =
10664 2.0f / 640.0f, 0.0f, 0.0f, 0.0f,
10665 0.0f, -2.0f / 480.0f, 0.0f, 0.0f,
10666 0.0f, 0.0f, 1.0f, 0.0f,
10667 -1.0f, 1.0f, 0.0f, 1.0f,
10668 }}};
10670 window = create_window();
10671 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10672 ok(!!d3d, "Failed to create a D3D object.\n");
10673 if (!(device = create_device(d3d, window, window, TRUE)))
10675 skip("Failed to create a D3D device, skipping tests.\n");
10676 goto done;
10679 memset(&caps, 0, sizeof(caps));
10680 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10681 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
10682 if(caps.MaxPointSize < 32.0) {
10683 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
10684 IDirect3DDevice9_Release(device);
10685 goto done;
10688 /* The r500 Windows driver needs a draw with regular texture coordinates at least once during the
10689 * device's lifetime, otherwise texture coordinate generation only works for texture 0. */
10690 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
10691 ok(SUCCEEDED(hr), "Failed to set FVF, hr=%#x.\n", hr);
10692 hr = IDirect3DDevice9_BeginScene(device);
10693 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10694 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, vertices, sizeof(float) * 5);
10695 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10696 hr = IDirect3DDevice9_EndScene(device);
10697 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10699 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10700 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
10701 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10702 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
10703 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
10704 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
10705 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10706 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
10708 hr = IDirect3DDevice9_BeginScene(device);
10709 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10711 ptsize = 15.0f;
10712 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10713 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10714 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
10715 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10717 ptsize = 31.0f;
10718 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10719 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10720 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
10721 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10723 ptsize = 30.75f;
10724 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10725 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10726 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
10727 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10729 if (caps.MaxPointSize >= 63.0f)
10731 ptsize = 63.0f;
10732 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10733 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10734 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
10735 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10737 ptsize = 62.75f;
10738 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10739 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10740 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
10741 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10744 ptsize = 1.0f;
10745 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10746 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10747 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
10748 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10750 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *)&ptsizemax_orig);
10751 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
10752 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *)&ptsizemin_orig);
10753 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
10755 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
10756 ptsize = 15.0f;
10757 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10758 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10759 ptsize = 1.0f;
10760 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsize);
10761 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10762 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
10763 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10765 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsizemax_orig);
10766 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10768 /* pointsize < pointsize_min < pointsize_max?
10769 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
10770 ptsize = 1.0f;
10771 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10772 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10773 ptsize = 15.0f;
10774 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
10775 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10776 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
10777 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10779 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsizemin_orig);
10780 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10782 hr = IDirect3DDevice9_EndScene(device);
10783 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10785 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
10786 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
10787 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
10789 if (caps.MaxPointSize >= 63.0)
10791 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
10792 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
10795 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
10796 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
10797 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
10798 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
10799 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
10801 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10803 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
10804 * generates texture coordinates for the point(result: Yes, it does)
10806 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
10807 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
10808 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
10810 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10811 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
10813 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
10814 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
10815 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
10816 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
10817 memset(&lr, 0, sizeof(lr));
10818 hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
10819 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
10820 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
10821 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
10822 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
10823 memset(&lr, 0, sizeof(lr));
10824 hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
10825 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
10826 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
10827 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
10828 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
10829 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
10830 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
10831 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
10832 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
10833 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10834 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10835 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10836 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10837 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
10838 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10839 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10840 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10841 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
10842 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10844 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
10845 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
10846 ptsize = 32.0;
10847 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
10848 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
10850 hr = IDirect3DDevice9_BeginScene(device);
10851 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10852 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
10853 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10854 hr = IDirect3DDevice9_EndScene(device);
10855 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10857 color = getPixelColor(device, 64-4, 64-4);
10858 ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
10859 color = getPixelColor(device, 64-4, 64+4);
10860 ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
10861 color = getPixelColor(device, 64+4, 64+4);
10862 ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
10863 color = getPixelColor(device, 64+4, 64-4);
10864 ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
10865 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10867 U(matrix).m[0][0] = 1.0f / 64.0f;
10868 U(matrix).m[1][1] = -1.0f / 64.0f;
10869 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
10870 ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
10872 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
10873 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10875 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
10876 D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
10877 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10879 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_A, *(DWORD *)&a);
10880 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
10881 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_B, *(DWORD *)&b);
10882 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
10883 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_C, *(DWORD *)&c);
10884 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
10885 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
10887 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, &S(U(matrix))._11, 4);
10888 ok(SUCCEEDED(hr), "Failed to set vertex shader constants, hr %#x.\n", hr);
10891 if (caps.MaxPointSize < 63.0f)
10893 skip("MaxPointSize %f < 63.0, skipping some tests.\n", caps.MaxPointSize);
10894 goto cleanup;
10897 for (i = 0; i < sizeof(test_setups) / sizeof(test_setups[0]); ++i)
10899 if (caps.VertexShaderVersion < test_setups[i].vs->version
10900 || caps.PixelShaderVersion < test_setups[i].ps->version)
10902 skip("Vertex / pixel shader version not supported, skipping test.\n");
10903 continue;
10905 if (test_setups[i].vs->code)
10907 hr = IDirect3DDevice9_CreateVertexShader(device, test_setups[i].vs->code, &vs);
10908 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
10910 else
10912 vs = NULL;
10914 if (test_setups[i].ps->code)
10916 hr = IDirect3DDevice9_CreatePixelShader(device, test_setups[i].ps->code, &ps);
10917 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
10919 else
10921 ps = NULL;
10924 hr = IDirect3DDevice9_SetVertexShader(device, vs);
10925 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
10926 hr = IDirect3DDevice9_SetPixelShader(device, ps);
10927 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
10929 for (j = 0; j < sizeof(tests) / sizeof(tests[0]); ++j)
10931 BOOL allow_broken = test_setups[i].allow_broken;
10932 unsigned int size = tests[j].override_min ? 63 : tests[j].zero_size ? 0 : tests[j].scale
10933 ? test_setups[i].scaled_size : test_setups[i].nonscaled_size;
10935 if (test_setups[i].accepted_fvf != tests[j].fvf)
10936 continue;
10938 ptsize = tests[j].zero_size ? 0.0f : 32.0f;
10939 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10940 ok(SUCCEEDED(hr), "Failed to set pointsize, hr %#x.\n", hr);
10942 ptsize = tests[j].override_min ? 63.0f : tests[j].zero_size ? 0.0f : ptsizemin_orig;
10943 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
10944 ok(SUCCEEDED(hr), "Failed to set minimum pointsize, hr %#x.\n", hr);
10946 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALEENABLE, tests[j].scale);
10947 ok(SUCCEEDED(hr), "Failed setting point scale state, hr %#x.\n", hr);
10949 hr = IDirect3DDevice9_SetFVF(device, tests[j].fvf);
10950 ok(SUCCEEDED(hr), "Failed setting FVF, hr %#x.\n", hr);
10952 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
10953 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10954 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
10955 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
10957 hr = IDirect3DDevice9_BeginScene(device);
10958 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10959 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1,
10960 tests[j].vertex_data, tests[j].vertex_size);
10961 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10962 hr = IDirect3DDevice9_EndScene(device);
10963 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10965 hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
10966 ok(SUCCEEDED(hr), "Failed to blit, hr %#x.\n", hr);
10967 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10968 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10970 if (tests[j].zero_size)
10972 /* Technically 0 pointsize is undefined in OpenGL but in practice it seems like
10973 * it does the "useful" thing on all the drivers I tried. */
10974 /* On WARP it does draw some pixels, most of the time. */
10975 color = getPixelColor(device, 64, 64);
10976 ok(color_match(color, 0x0000ffff, 0)
10977 || broken(color_match(color, 0x00ff0000, 0))
10978 || broken(color_match(color, 0x00ffff00, 0))
10979 || broken(color_match(color, 0x00000000, 0))
10980 || broken(color_match(color, 0x0000ff00, 0)),
10981 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10983 else
10985 struct surface_readback rb;
10987 get_rt_readback(backbuffer, &rb);
10988 /* On AMD apparently only the first texcoord is modified by the point coordinates
10989 * when using SM2/3 pixel shaders. */
10990 color = get_readback_color(&rb, 64 - size / 2 + 1, 64 - size / 2 + 1);
10991 ok(color_match(color, 0x00ff0000, 0),
10992 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10993 color = get_readback_color(&rb, 64 + size / 2 - 1, 64 - size / 2 + 1);
10994 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x00ffff00, 0)
10995 || (allow_broken && broken(color_match(color, 0x00ff0000, 0))),
10996 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10997 color = get_readback_color(&rb, 64 - size / 2 + 1, 64 + size / 2 - 1);
10998 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x00000000, 0),
10999 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
11000 color = get_readback_color(&rb, 64 + size / 2 - 1, 64 + size / 2 - 1);
11001 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x0000ff00, 0)
11002 || (allow_broken && broken(color_match(color, 0x00000000, 0))),
11003 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
11005 color = get_readback_color(&rb, 64 - size / 2 - 1, 64 - size / 2 - 1);
11006 ok(color_match(color, 0xff00ffff, 0),
11007 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
11008 color = get_readback_color(&rb, 64 + size / 2 + 1, 64 - size / 2 - 1);
11009 ok(color_match(color, 0xff00ffff, 0),
11010 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
11011 color = get_readback_color(&rb, 64 - size / 2 - 1, 64 + size / 2 + 1);
11012 ok(color_match(color, 0xff00ffff, 0),
11013 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
11014 color = get_readback_color(&rb, 64 + size / 2 + 1, 64 + size / 2 + 1);
11015 ok(color_match(color, 0xff00ffff, 0),
11016 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
11018 release_surface_readback(&rb);
11021 IDirect3DDevice9_SetVertexShader(device, NULL);
11022 IDirect3DDevice9_SetPixelShader(device, NULL);
11023 if (vs)
11024 IDirect3DVertexShader9_Release(vs);
11025 if (ps)
11026 IDirect3DVertexShader9_Release(ps);
11029 cleanup:
11030 IDirect3DSurface9_Release(backbuffer);
11031 IDirect3DSurface9_Release(rt);
11033 IDirect3DTexture9_Release(tex1);
11034 IDirect3DTexture9_Release(tex2);
11035 refcount = IDirect3DDevice9_Release(device);
11036 ok(!refcount, "Device has %u references left.\n", refcount);
11037 done:
11038 IDirect3D9_Release(d3d);
11039 DestroyWindow(window);
11042 static void multiple_rendertargets_test(void)
11044 IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
11045 IDirect3DPixelShader9 *ps1, *ps2;
11046 IDirect3DTexture9 *tex1, *tex2;
11047 IDirect3DVertexShader9 *vs;
11048 IDirect3DDevice9 *device;
11049 IDirect3D9 *d3d;
11050 ULONG refcount;
11051 D3DCAPS9 caps;
11052 DWORD color;
11053 HWND window;
11054 HRESULT hr;
11055 UINT i, j;
11057 static const DWORD vshader_code[] =
11059 0xfffe0300, /* vs_3_0 */
11060 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11061 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
11062 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
11063 0x0000ffff /* end */
11065 static const DWORD pshader_code1[] =
11067 0xffff0300, /* ps_3_0 */
11068 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
11069 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
11070 0x0000ffff /* end */
11072 static const DWORD pshader_code2[] =
11074 0xffff0300, /* ps_3_0 */
11075 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
11076 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
11077 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
11078 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
11079 0x0000ffff /* end */
11081 static const float quad[] =
11083 -1.0f, -1.0f, 0.1f,
11084 -1.0f, 1.0f, 0.1f,
11085 1.0f, -1.0f, 0.1f,
11086 1.0f, 1.0f, 0.1f,
11088 static const float texquad[] =
11090 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
11091 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
11092 0.0f, -1.0f, 0.1f, 1.0f, 0.0f,
11093 0.0f, 1.0f, 0.1f, 1.0f, 1.0f,
11095 0.0f, -1.0f, 0.1f, 0.0f, 0.0f,
11096 0.0f, 1.0f, 0.1f, 0.0f, 1.0f,
11097 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
11098 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
11101 window = create_window();
11102 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11103 ok(!!d3d, "Failed to create a D3D object.\n");
11104 if (!(device = create_device(d3d, window, window, TRUE)))
11106 skip("Failed to create a D3D device, skipping tests.\n");
11107 goto done;
11110 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11111 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
11112 if (caps.NumSimultaneousRTs < 2)
11114 skip("Only 1 simultaneous render target supported, skipping MRT test.\n");
11115 IDirect3DDevice9_Release(device);
11116 goto done;
11118 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
11120 skip("No shader model 3 support, skipping tests.\n");
11121 IDirect3DDevice9_Release(device);
11122 goto done;
11125 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
11126 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
11128 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
11129 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
11130 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
11132 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
11133 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
11134 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
11135 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
11136 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
11137 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
11138 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
11139 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
11140 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code1, &ps1);
11141 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
11142 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code2, &ps2);
11143 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
11145 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
11146 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
11147 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
11148 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
11149 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
11150 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
11152 hr = IDirect3DDevice9_SetVertexShader(device, vs);
11153 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
11154 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
11155 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11156 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
11157 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11158 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
11159 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
11161 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
11162 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
11163 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
11164 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11165 color = getPixelColorFromSurface(readback, 8, 8);
11166 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
11167 "Expected color 0x000000ff, got 0x%08x.\n", color);
11168 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
11169 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11170 color = getPixelColorFromSurface(readback, 8, 8);
11171 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
11172 "Expected color 0x000000ff, got 0x%08x.\n", color);
11174 /* Render targets not written by the pixel shader should be unmodified. */
11175 hr = IDirect3DDevice9_SetPixelShader(device, ps1);
11176 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
11177 hr = IDirect3DDevice9_BeginScene(device);
11178 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11179 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
11180 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11181 hr = IDirect3DDevice9_EndScene(device);
11182 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11183 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
11184 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11185 color = getPixelColorFromSurface(readback, 8, 8);
11186 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
11187 "Expected color 0xff00ff00, got 0x%08x.\n", color);
11188 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
11189 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11190 for (i = 6; i < 10; ++i)
11192 for (j = 6; j < 10; ++j)
11194 color = getPixelColorFromSurface(readback, j, i);
11195 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
11196 "Expected color 0xff0000ff, got 0x%08x at %u, %u.\n", color, j, i);
11200 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
11201 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
11202 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
11203 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11204 color = getPixelColorFromSurface(readback, 8, 8);
11205 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
11206 "Expected color 0x0000ff00, got 0x%08x.\n", color);
11207 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
11208 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11209 color = getPixelColorFromSurface(readback, 8, 8);
11210 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
11211 "Expected color 0x0000ff00, got 0x%08x.\n", color);
11213 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
11214 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
11216 hr = IDirect3DDevice9_BeginScene(device);
11217 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11219 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
11220 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11222 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11223 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11224 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11225 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
11226 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11227 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
11228 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
11229 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11230 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
11231 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11232 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11233 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
11235 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
11236 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
11237 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
11238 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11240 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
11241 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
11242 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
11243 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11245 hr = IDirect3DDevice9_EndScene(device);
11246 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11248 color = getPixelColor(device, 160, 240);
11249 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
11250 color = getPixelColor(device, 480, 240);
11251 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
11252 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11254 IDirect3DPixelShader9_Release(ps2);
11255 IDirect3DPixelShader9_Release(ps1);
11256 IDirect3DVertexShader9_Release(vs);
11257 IDirect3DTexture9_Release(tex1);
11258 IDirect3DTexture9_Release(tex2);
11259 IDirect3DSurface9_Release(surf1);
11260 IDirect3DSurface9_Release(surf2);
11261 IDirect3DSurface9_Release(backbuf);
11262 IDirect3DSurface9_Release(readback);
11263 refcount = IDirect3DDevice9_Release(device);
11264 ok(!refcount, "Device has %u references left.\n", refcount);
11265 done:
11266 IDirect3D9_Release(d3d);
11267 DestroyWindow(window);
11270 static void pixelshader_blending_test(void)
11272 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
11273 IDirect3DTexture9 *offscreenTexture = NULL;
11274 IDirect3DDevice9 *device;
11275 IDirect3D9 *d3d;
11276 ULONG refcount;
11277 int fmt_index;
11278 DWORD color;
11279 HWND window;
11280 HRESULT hr;
11282 static const struct
11284 const char *fmtName;
11285 D3DFORMAT textureFormat;
11286 D3DCOLOR resultColorBlending;
11287 D3DCOLOR resultColorNoBlending;
11289 test_formats[] =
11291 {"D3DFMT_G16R16", D3DFMT_G16R16, 0x001820ff, 0x002010ff},
11292 {"D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff},
11293 {"D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001820ff, 0x002010ff},
11294 {"D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00182000, 0x00201000},
11295 {"D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff},
11296 {"D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001820ff, 0x002010ff},
11297 {"D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00182000, 0x00201000},
11298 {"D3DFMT_L8", D3DFMT_L8, 0x00181818, 0x00202020},
11300 static const float quad[][5] =
11302 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
11303 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
11304 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
11305 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
11307 static const struct
11309 struct vec3 position;
11310 DWORD diffuse;
11312 quad1[] =
11314 {{-1.0f, -1.0f, 0.1f}, 0x80103000},
11315 {{-1.0f, 1.0f, 0.1f}, 0x80103000},
11316 {{ 1.0f, -1.0f, 0.1f}, 0x80103000},
11317 {{ 1.0f, 1.0f, 0.1f}, 0x80103000},
11319 quad2[] =
11321 {{-1.0f, -1.0f, 0.1f}, 0x80201000},
11322 {{-1.0f, 1.0f, 0.1f}, 0x80201000},
11323 {{ 1.0f, -1.0f, 0.1f}, 0x80201000},
11324 {{ 1.0f, 1.0f, 0.1f}, 0x80201000},
11327 window = create_window();
11328 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11329 ok(!!d3d, "Failed to create a D3D object.\n");
11330 if (!(device = create_device(d3d, window, window, TRUE)))
11332 skip("Failed to create a D3D device, skipping tests.\n");
11333 goto done;
11336 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
11337 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
11339 for (fmt_index = 0; fmt_index < sizeof(test_formats) / sizeof(*test_formats); ++fmt_index)
11341 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
11343 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11344 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
11346 skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
11347 continue;
11350 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
11351 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
11353 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
11354 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
11355 if(!offscreenTexture) {
11356 continue;
11359 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
11360 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
11361 if(!offscreen) {
11362 continue;
11365 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11366 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
11368 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11369 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11370 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
11371 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11372 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11373 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
11374 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11375 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
11376 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11377 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
11379 /* Below we will draw two quads with different colors and try to blend
11380 * them together. The result color is compared with the expected
11381 * outcome. */
11382 hr = IDirect3DDevice9_BeginScene(device);
11383 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11385 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
11386 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11387 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 1.0f, 0);
11388 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
11390 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
11391 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11393 /* Draw a quad using color 0x0010200. */
11394 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
11395 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11396 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
11397 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11398 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
11399 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11401 /* Draw a quad using color 0x0020100. */
11402 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
11403 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11404 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
11405 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11406 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
11407 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11409 /* We don't want to blend the result on the backbuffer. */
11410 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
11411 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11413 /* Prepare rendering the 'blended' texture quad to the backbuffer. */
11414 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11415 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11416 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)offscreenTexture);
11417 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
11419 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11420 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
11422 /* This time with the texture. */
11423 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
11424 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11426 hr = IDirect3DDevice9_EndScene(device);
11427 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11429 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11430 D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK)
11432 /* Compare the color of the center quad with our expectation. */
11433 color = getPixelColor(device, 320, 240);
11434 ok(color_match(color, test_formats[fmt_index].resultColorBlending, 1),
11435 "Offscreen failed for %s: Got color 0x%08x, expected 0x%08x.\n",
11436 test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
11438 else
11440 /* No pixel shader blending is supported so expect garbage. The
11441 * type of 'garbage' depends on the driver version and OS. E.g. on
11442 * G16R16 ATI reports (on old r9600 drivers) 0x00ffffff and on
11443 * modern ones 0x002010ff which is also what NVIDIA reports. On
11444 * Vista NVIDIA seems to report 0x00ffffff on Geforce7 cards. */
11445 color = getPixelColor(device, 320, 240);
11446 ok((color == 0x00ffffff) || (color == test_formats[fmt_index].resultColorNoBlending),
11447 "Offscreen failed for %s: Got unexpected color 0x%08x, expected no color blending.\n",
11448 test_formats[fmt_index].fmtName, color);
11450 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11452 IDirect3DDevice9_SetTexture(device, 0, NULL);
11453 if(offscreenTexture) {
11454 IDirect3DTexture9_Release(offscreenTexture);
11456 if(offscreen) {
11457 IDirect3DSurface9_Release(offscreen);
11461 IDirect3DSurface9_Release(backbuffer);
11462 refcount = IDirect3DDevice9_Release(device);
11463 ok(!refcount, "Device has %u references left.\n", refcount);
11464 done:
11465 IDirect3D9_Release(d3d);
11466 DestroyWindow(window);
11469 static void tssargtemp_test(void)
11471 IDirect3DDevice9 *device;
11472 IDirect3D9 *d3d;
11473 D3DCOLOR color;
11474 ULONG refcount;
11475 D3DCAPS9 caps;
11476 HWND window;
11477 HRESULT hr;
11479 static const struct
11481 struct vec3 position;
11482 DWORD diffuse;
11484 quad[] =
11486 {{-1.0f, -1.0f, 0.1f}, 0x00ff0000},
11487 {{-1.0f, 1.0f, 0.1f}, 0x00ff0000},
11488 {{ 1.0f, -1.0f, 0.1f}, 0x00ff0000},
11489 {{ 1.0f, 1.0f, 0.1f}, 0x00ff0000},
11492 window = create_window();
11493 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11494 ok(!!d3d, "Failed to create a D3D object.\n");
11495 if (!(device = create_device(d3d, window, window, TRUE)))
11497 skip("Failed to create a D3D device, skipping tests.\n");
11498 goto done;
11501 memset(&caps, 0, sizeof(caps));
11502 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11503 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
11504 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
11505 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
11506 IDirect3DDevice9_Release(device);
11507 goto done;
11510 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
11511 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11513 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11514 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11515 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
11516 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11518 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11519 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11520 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
11521 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11522 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
11523 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11525 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
11526 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11527 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
11528 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11529 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
11530 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11532 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
11533 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11535 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
11536 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
11537 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11538 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
11539 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11540 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
11542 hr = IDirect3DDevice9_BeginScene(device);
11543 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11544 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
11545 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11546 hr = IDirect3DDevice9_EndScene(device);
11547 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11549 color = getPixelColor(device, 320, 240);
11550 ok(color == 0x00ffff00, "TSSARGTEMP test returned color 0x%08x, expected 0x00ffff00\n", color);
11551 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11553 refcount = IDirect3DDevice9_Release(device);
11554 ok(!refcount, "Device has %u references left.\n", refcount);
11555 done:
11556 IDirect3D9_Release(d3d);
11557 DestroyWindow(window);
11560 /* Drawing Indexed Geometry with instances*/
11561 static void stream_test(void)
11563 IDirect3DVertexDeclaration9 *pDecl = NULL;
11564 IDirect3DVertexShader9 *shader = NULL;
11565 IDirect3DVertexBuffer9 *vb3 = NULL;
11566 IDirect3DVertexBuffer9 *vb2 = NULL;
11567 IDirect3DVertexBuffer9 *vb = NULL;
11568 IDirect3DIndexBuffer9 *ib = NULL;
11569 IDirect3DDevice9 *device;
11570 IDirect3D9 *d3d;
11571 ULONG refcount;
11572 D3DCAPS9 caps;
11573 DWORD color;
11574 HWND window;
11575 unsigned i;
11576 HRESULT hr;
11577 BYTE *data;
11578 DWORD ind;
11580 static const struct testdata
11582 DWORD idxVertex; /* number of instances in the first stream */
11583 DWORD idxColor; /* number of instances in the second stream */
11584 DWORD idxInstance; /* should be 1 ?? */
11585 DWORD color1; /* color 1 instance */
11586 DWORD color2; /* color 2 instance */
11587 DWORD color3; /* color 3 instance */
11588 DWORD color4; /* color 4 instance */
11589 WORD strVertex; /* specify which stream to use 0-2*/
11590 WORD strColor;
11591 WORD strInstance;
11592 DWORD explicit_zero_freq;
11594 testcases[]=
11596 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
11597 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
11598 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
11599 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
11600 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 4 */
11601 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
11602 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
11603 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
11604 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 8 */
11605 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 9 */
11606 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 10 */
11607 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 11 */
11609 /* The number of instances is read from stream zero, even if stream zero is not
11610 * in use. Exact behavior of this corner case depends on the presence or absence
11611 * of D3DSTREAMSOURCE_INDEXEDDATA. r500 GPUs need D3DSTREAMSOURCE_INDEXEDDATA
11612 * to be present, otherwise they disable instancing and behave like in a non-
11613 * instanced draw. Nvidia drivers do not show different behavior with or without
11614 * D3DSTREAMSOURCE_INDEXEDDATA. Note however that setting the value to 0 is not
11615 * allowed by the d3d runtime.
11617 * The meaning of (D3DSTREAMSOURCE_INDEXEDDATA | 0) is driver dependent. r500
11618 * will fall back to non-instanced drawing. Geforce 7 will draw 1 instance.
11619 * Geforce 8+ will draw nothing. */
11620 {3, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1, 1}, /* 12 */
11621 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 2, 3, 1, 2}, /* 13 */
11622 {1, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 2, 3, 1, 3}, /* 14 */
11623 {0, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 3, 1, 4}, /* 15 */
11625 static const DWORD shader_code[] =
11627 0xfffe0101, /* vs_1_1 */
11628 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11629 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
11630 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
11631 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
11632 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
11633 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
11634 0x0000ffff
11636 /* Note that this set of coordinates and instancepos[] have an implicit
11637 * w = 1.0, which is added to w = 2.0, so the perspective divide divides
11638 * x, y and z by 2. */
11639 static const float quad[][3] =
11641 {-0.5f, -0.5f, 1.1f}, /*0 */
11642 {-0.5f, 0.5f, 1.1f}, /*1 */
11643 { 0.5f, -0.5f, 1.1f}, /*2 */
11644 { 0.5f, 0.5f, 1.1f}, /*3 */
11646 static const float vertcolor[][4] =
11648 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
11649 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
11650 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
11651 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
11653 /* 4 position for 4 instances */
11654 static const float instancepos[][3] =
11656 {-0.6f,-0.6f, 0.0f},
11657 { 0.6f,-0.6f, 0.0f},
11658 { 0.6f, 0.6f, 0.0f},
11659 {-0.6f, 0.6f, 0.0f},
11661 static const short indices[] = {0, 1, 2, 2, 1, 3};
11662 D3DVERTEXELEMENT9 decl[] =
11664 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
11665 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
11666 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
11667 D3DDECL_END()
11670 window = create_window();
11671 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11672 ok(!!d3d, "Failed to create a D3D object.\n");
11673 if (!(device = create_device(d3d, window, window, TRUE)))
11675 skip("Failed to create a D3D device, skipping tests.\n");
11676 goto done;
11679 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11680 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
11681 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
11683 skip("No vs_3_0 support, skipping tests.\n");
11684 IDirect3DDevice9_Release(device);
11685 goto done;
11688 /* set the default value because it isn't done in wine? */
11689 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
11690 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11692 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
11693 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
11694 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11696 /* check wrong cases */
11697 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
11698 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11699 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11700 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11701 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
11702 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11703 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11704 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11705 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
11706 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11707 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11708 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11709 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
11710 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11711 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11712 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11713 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
11714 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11715 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11716 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11718 /* set the default value back */
11719 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
11720 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11722 /* create all VertexBuffers*/
11723 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
11724 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
11725 if(!vb) {
11726 skip("Failed to create a vertex buffer\n");
11727 IDirect3DDevice9_Release(device);
11728 goto done;
11730 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
11731 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
11732 if(!vb2) {
11733 skip("Failed to create a vertex buffer\n");
11734 goto out;
11736 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
11737 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
11738 if(!vb3) {
11739 skip("Failed to create a vertex buffer\n");
11740 goto out;
11743 /* create IndexBuffer*/
11744 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
11745 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
11746 if(!ib) {
11747 skip("Failed to create an index buffer\n");
11748 goto out;
11751 /* copy all Buffers (Vertex + Index)*/
11752 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
11753 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
11754 memcpy(data, quad, sizeof(quad));
11755 hr = IDirect3DVertexBuffer9_Unlock(vb);
11756 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
11757 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
11758 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
11759 memcpy(data, vertcolor, sizeof(vertcolor));
11760 hr = IDirect3DVertexBuffer9_Unlock(vb2);
11761 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
11762 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
11763 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
11764 memcpy(data, instancepos, sizeof(instancepos));
11765 hr = IDirect3DVertexBuffer9_Unlock(vb3);
11766 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
11767 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
11768 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
11769 memcpy(data, indices, sizeof(indices));
11770 hr = IDirect3DIndexBuffer9_Unlock(ib);
11771 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
11773 /* create VertexShader */
11774 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
11775 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
11776 if(!shader) {
11777 skip("Failed to create a vertex shader.\n");
11778 goto out;
11781 hr = IDirect3DDevice9_SetVertexShader(device, shader);
11782 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
11784 hr = IDirect3DDevice9_SetIndices(device, ib);
11785 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
11787 /* run all tests */
11788 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
11790 struct testdata act = testcases[i];
11791 decl[0].Stream = act.strVertex;
11792 decl[1].Stream = act.strColor;
11793 decl[2].Stream = act.strInstance;
11794 /* create VertexDeclarations */
11795 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
11796 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
11798 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
11799 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
11801 hr = IDirect3DDevice9_BeginScene(device);
11802 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11804 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
11805 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
11807 /* If stream 0 is unused, set the stream frequency regardless to show
11808 * that the number if instances is read from it. */
11809 if (act.strVertex && act.strColor && act.strInstance)
11811 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0,
11812 D3DSTREAMSOURCE_INDEXEDDATA | act.explicit_zero_freq);
11813 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11816 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex,
11817 (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
11818 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11819 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
11820 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11822 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor,
11823 (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
11824 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11825 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
11826 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11828 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance,
11829 (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
11830 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11831 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
11832 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11834 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
11835 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11836 hr = IDirect3DDevice9_EndScene(device);
11837 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11839 /* set all StreamSource && StreamSourceFreq back to default */
11840 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
11841 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11842 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
11843 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11844 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
11845 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11846 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
11847 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11848 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
11849 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11850 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
11851 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11853 hr = IDirect3DVertexDeclaration9_Release(pDecl);
11854 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
11856 color = getPixelColor(device, 160, 360);
11857 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
11858 color = getPixelColor(device, 480, 360);
11859 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
11860 color = getPixelColor(device, 480, 120);
11861 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
11862 color = getPixelColor(device, 160, 120);
11863 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
11865 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11866 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
11869 out:
11870 if(vb) IDirect3DVertexBuffer9_Release(vb);
11871 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
11872 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
11873 if(ib)IDirect3DIndexBuffer9_Release(ib);
11874 if(shader)IDirect3DVertexShader9_Release(shader);
11875 refcount = IDirect3DDevice9_Release(device);
11876 ok(!refcount, "Device has %u references left.\n", refcount);
11877 done:
11878 IDirect3D9_Release(d3d);
11879 DestroyWindow(window);
11882 static void np2_stretch_rect_test(void)
11884 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
11885 IDirect3DTexture9 *dsttex = NULL;
11886 IDirect3DDevice9 *device;
11887 IDirect3D9 *d3d;
11888 D3DCOLOR color;
11889 ULONG refcount;
11890 HWND window;
11891 HRESULT hr;
11893 static const D3DRECT r1 = {0, 0, 50, 50 };
11894 static const D3DRECT r2 = {50, 0, 100, 50 };
11895 static const D3DRECT r3 = {50, 50, 100, 100};
11896 static const D3DRECT r4 = {0, 50, 50, 100};
11897 static const float quad[] =
11899 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
11900 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
11901 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
11902 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
11905 window = create_window();
11906 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11907 ok(!!d3d, "Failed to create a D3D object.\n");
11908 if (!(device = create_device(d3d, window, window, TRUE)))
11910 skip("Failed to create a D3D device, skipping tests.\n");
11911 goto done;
11914 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
11915 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
11917 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
11918 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
11919 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
11920 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
11922 if(!src || !dsttex) {
11923 skip("One or more test resources could not be created\n");
11924 goto cleanup;
11927 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
11928 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
11930 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
11931 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11933 /* Clear the StretchRect destination for debugging */
11934 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
11935 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
11936 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
11937 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11939 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
11940 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
11942 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
11943 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11944 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
11945 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11946 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
11947 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11948 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
11949 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11951 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
11952 * the target -> texture GL blit path
11954 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
11955 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
11956 IDirect3DSurface9_Release(dst);
11958 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11959 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
11961 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
11962 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
11963 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11964 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
11965 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11966 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
11967 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
11968 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
11970 hr = IDirect3DDevice9_BeginScene(device);
11971 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11972 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
11973 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11974 hr = IDirect3DDevice9_EndScene(device);
11975 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11977 color = getPixelColor(device, 160, 360);
11978 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
11979 color = getPixelColor(device, 480, 360);
11980 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
11981 color = getPixelColor(device, 480, 120);
11982 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
11983 color = getPixelColor(device, 160, 120);
11984 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
11985 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11986 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
11988 cleanup:
11989 if(src) IDirect3DSurface9_Release(src);
11990 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
11991 if(dsttex) IDirect3DTexture9_Release(dsttex);
11992 refcount = IDirect3DDevice9_Release(device);
11993 ok(!refcount, "Device has %u references left.\n", refcount);
11994 done:
11995 IDirect3D9_Release(d3d);
11996 DestroyWindow(window);
11999 static void texop_test(void)
12001 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
12002 IDirect3DTexture9 *texture = NULL;
12003 D3DLOCKED_RECT locked_rect;
12004 IDirect3DDevice9 *device;
12005 IDirect3D9 *d3d;
12006 D3DCOLOR color;
12007 ULONG refcount;
12008 D3DCAPS9 caps;
12009 HWND window;
12010 HRESULT hr;
12011 unsigned i;
12013 static const struct {
12014 float x, y, z;
12015 float s, t;
12016 D3DCOLOR diffuse;
12017 } quad[] = {
12018 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
12019 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
12020 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
12021 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
12024 static const D3DVERTEXELEMENT9 decl_elements[] = {
12025 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
12026 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
12027 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
12028 D3DDECL_END()
12031 static const struct {
12032 D3DTEXTUREOP op;
12033 const char *name;
12034 DWORD caps_flag;
12035 D3DCOLOR result;
12036 } test_data[] = {
12037 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
12038 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
12039 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
12040 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
12041 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
12042 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
12043 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
12044 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
12045 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
12046 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
12047 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
12048 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
12049 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
12050 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
12051 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
12052 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
12053 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
12054 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
12055 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
12056 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
12057 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT3", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
12058 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
12059 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
12062 window = create_window();
12063 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12064 ok(!!d3d, "Failed to create a D3D object.\n");
12065 if (!(device = create_device(d3d, window, window, TRUE)))
12067 skip("Failed to create a D3D device, skipping tests.\n");
12068 goto done;
12071 memset(&caps, 0, sizeof(caps));
12072 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12073 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
12075 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
12076 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
12077 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
12078 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
12080 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
12081 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
12082 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
12083 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
12084 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
12085 hr = IDirect3DTexture9_UnlockRect(texture, 0);
12086 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
12087 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
12088 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
12090 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
12091 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12092 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12093 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12094 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12095 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12097 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
12098 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12100 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12101 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12102 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
12103 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12104 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
12105 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12107 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12108 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12110 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
12112 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
12114 skip("tex operation %s not supported\n", test_data[i].name);
12115 continue;
12118 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
12119 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
12121 hr = IDirect3DDevice9_BeginScene(device);
12122 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
12124 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12125 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
12127 hr = IDirect3DDevice9_EndScene(device);
12128 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
12130 color = getPixelColor(device, 320, 240);
12131 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
12132 test_data[i].name, color, test_data[i].result);
12134 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12135 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12138 IDirect3DTexture9_Release(texture);
12139 IDirect3DVertexDeclaration9_Release(vertex_declaration);
12140 refcount = IDirect3DDevice9_Release(device);
12141 ok(!refcount, "Device has %u references left.\n", refcount);
12142 done:
12143 IDirect3D9_Release(d3d);
12144 DestroyWindow(window);
12147 static void yuv_color_test(void)
12149 HRESULT hr;
12150 IDirect3DSurface9 *surface, *target;
12151 unsigned int i;
12152 D3DLOCKED_RECT lr;
12153 IDirect3D9 *d3d;
12154 D3DCOLOR color;
12155 D3DFORMAT skip_once = D3DFMT_UNKNOWN;
12156 IDirect3DDevice9 *device;
12157 D3DSURFACE_DESC desc;
12158 ULONG refcount;
12159 HWND window;
12161 static const struct
12163 DWORD in;
12164 D3DFORMAT format;
12165 const char *fmt_string;
12166 D3DCOLOR left, right;
12168 test_data[] =
12170 {0x00000000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00008700, 0x00008700},
12171 {0xff000000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00008700, 0x004bff1c},
12172 {0x00ff0000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b30000, 0x00b30000},
12173 {0x0000ff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bff1c, 0x00008700},
12174 {0x000000ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000030e1, 0x000030e1},
12175 {0xffff0000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b30000, 0x00ffd01c},
12176 {0xff00ff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bff1c, 0x004bff1c},
12177 {0xff0000ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000030e1, 0x004bffff},
12178 {0x00ffff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffd01c, 0x00b30000},
12179 {0x00ff00ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b300e1, 0x00b300e1},
12180 {0x0000ffff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bffff, 0x001030e1},
12181 {0xffffff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffd01c, 0x00ffd01c},
12182 {0xffff00ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b300e1, 0x00ff79ff},
12183 {0xffffffff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ff79ff, 0x00ff79ff},
12184 {0x4cff4c54, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ff0000, 0x00ff0000},
12185 {0x00800080, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00000000, 0x00000000},
12186 {0xff80ff80, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffffff, 0x00ffffff},
12187 {0x1c6b1cff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000000fd, 0x000000fd},
12189 {0x00000000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00008700, 0x00008700},
12190 {0xff000000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b30000, 0x00b30000},
12191 {0x00ff0000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00008700, 0x004bff1c},
12192 {0x0000ff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000030e1, 0x000030e1},
12193 {0x000000ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bff1c, 0x00008700},
12194 {0xffff0000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b30000, 0x00ffd01c},
12195 {0xff00ff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b300e1, 0x00b300e1},
12196 {0xff0000ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ffd01c, 0x00b30000},
12197 {0x00ffff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000030e1, 0x004bffff},
12198 {0x00ff00ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bff1c, 0x004bff1c},
12199 {0x0000ffff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bffff, 0x000030e1},
12200 {0xffffff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b300e1, 0x00ff79ff},
12201 {0xffff00ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ffd01c, 0x00ffd01c},
12202 {0xffffffff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ff79ff, 0x00ff79ff},
12203 {0x4cff4c54, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000b8b00, 0x00b6ffa3},
12204 {0x00800080, D3DFMT_YUY2, "D3DFMT_YUY2", 0x0000ff00, 0x0000ff00},
12205 {0xff80ff80, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ff00ff, 0x00ff00ff},
12206 {0x1c6b1cff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x006dff45, 0x0000d500},
12209 window = create_window();
12210 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12211 ok(!!d3d, "Failed to create a D3D object.\n");
12212 if (!(device = create_device(d3d, window, window, TRUE)))
12214 skip("Failed to create a D3D device, skipping tests.\n");
12215 goto done;
12218 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
12219 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
12220 hr = IDirect3DSurface9_GetDesc(target, &desc);
12221 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
12223 for (i = 0; i < sizeof(test_data) / sizeof(test_data[0]); i++)
12225 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect.
12226 * Thus use StretchRect to draw the YUV surface onto the screen instead of drawPrimitive. */
12227 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
12228 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, test_data[i].format)))
12230 if (skip_once != test_data[i].format)
12232 skip("%s is not supported.\n", test_data[i].fmt_string);
12233 skip_once = test_data[i].format;
12235 continue;
12237 if (FAILED(IDirect3D9_CheckDeviceFormatConversion(d3d, 0,
12238 D3DDEVTYPE_HAL, test_data[i].format, desc.Format)))
12240 if (skip_once != test_data[i].format)
12242 skip("Driver cannot blit %s surfaces.\n", test_data[i].fmt_string);
12243 skip_once = test_data[i].format;
12245 continue;
12248 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1.
12249 * However, Nvidia Windows drivers have problems with 2x1 YUY2/UYVY surfaces, so use a 4x1 surface and
12250 * fill the second block with dummy data. If the surface has a size of 2x1, those drivers ignore the
12251 * second luminance value, resulting in an incorrect color in the right pixel. */
12252 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 1, test_data[i].format,
12253 D3DPOOL_DEFAULT, &surface, NULL);
12254 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
12257 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
12258 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
12259 ((DWORD *)lr.pBits)[0] = test_data[i].in;
12260 ((DWORD *)lr.pBits)[1] = 0x00800080;
12261 hr = IDirect3DSurface9_UnlockRect(surface);
12262 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
12264 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
12265 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
12266 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
12267 ok(SUCCEEDED(hr), "Failed to draw surface onto backbuffer, hr %#x.\n", hr);
12269 /* Some Windows drivers (mostly Nvidia, but also some VM drivers) insist on doing linear filtering
12270 * although we asked for point filtering. Be careful when reading the results and use the pixel
12271 * centers. In the future we may want to add tests for the filtered pixels as well.
12273 * Unfortunately different implementations(Windows-Nvidia and Mac-AMD tested) interpret some colors
12274 * vastly differently, so we need a max diff of 18. */
12275 color = getPixelColor(device, 1, 240);
12276 ok(color_match(color, test_data[i].left, 18),
12277 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s.\n",
12278 test_data[i].in, color, test_data[i].left, test_data[i].fmt_string);
12279 color = getPixelColor(device, 318, 240);
12280 ok(color_match(color, test_data[i].right, 18),
12281 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s.\n",
12282 test_data[i].in, color, test_data[i].right, test_data[i].fmt_string);
12283 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12284 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
12285 IDirect3DSurface9_Release(surface);
12288 IDirect3DSurface9_Release(target);
12289 refcount = IDirect3DDevice9_Release(device);
12290 ok(!refcount, "Device has %u references left.\n", refcount);
12291 done:
12292 IDirect3D9_Release(d3d);
12293 DestroyWindow(window);
12296 static void yuv_layout_test(void)
12298 HRESULT hr;
12299 IDirect3DSurface9 *surface, *target;
12300 unsigned int fmt, i, x, y;
12301 D3DFORMAT format;
12302 const char *fmt_string;
12303 D3DLOCKED_RECT lr;
12304 IDirect3D9 *d3d;
12305 D3DCOLOR color;
12306 DWORD ref_color;
12307 BYTE *buf, *chroma_buf, *u_buf, *v_buf;
12308 UINT width = 20, height = 16;
12309 IDirect3DDevice9 *device;
12310 ULONG refcount;
12311 D3DCAPS9 caps;
12312 D3DSURFACE_DESC desc;
12313 HWND window;
12315 static const struct
12317 DWORD color1, color2;
12318 DWORD rgb1, rgb2;
12320 test_data[] =
12322 { 0x000000, 0xffffff, 0x00008800, 0x00ff7dff },
12323 { 0xff0000, 0x00ffff, 0x004aff14, 0x00b800ee },
12324 { 0x00ff00, 0xff00ff, 0x000024ee, 0x00ffe114 },
12325 { 0x0000ff, 0xffff00, 0x00b80000, 0x004affff },
12326 { 0xffff00, 0x0000ff, 0x004affff, 0x00b80000 },
12327 { 0xff00ff, 0x00ff00, 0x00ffe114, 0x000024ee },
12328 { 0x00ffff, 0xff0000, 0x00b800ee, 0x004aff14 },
12329 { 0xffffff, 0x000000, 0x00ff7dff, 0x00008800 },
12332 static const struct
12334 D3DFORMAT format;
12335 const char *str;
12337 formats[] =
12339 { D3DFMT_UYVY, "D3DFMT_UYVY", },
12340 { D3DFMT_YUY2, "D3DFMT_YUY2", },
12341 { MAKEFOURCC('Y','V','1','2'), "D3DFMT_YV12", },
12342 { MAKEFOURCC('N','V','1','2'), "D3DFMT_NV12", },
12345 window = create_window();
12346 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12347 ok(!!d3d, "Failed to create a D3D object.\n");
12348 if (!(device = create_device(d3d, window, window, TRUE)))
12350 skip("Failed to create a D3D device, skipping tests.\n");
12351 goto done;
12354 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12355 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
12356 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2
12357 && !(caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL))
12359 skip("No NP2 texture support, skipping YUV texture layout test.\n");
12360 IDirect3DDevice9_Release(device);
12361 goto done;
12364 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
12365 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %#x.\n", hr);
12366 hr = IDirect3DSurface9_GetDesc(target, &desc);
12367 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
12369 for (fmt = 0; fmt < sizeof(formats) / sizeof(formats[0]); fmt++)
12371 format = formats[fmt].format;
12372 fmt_string = formats[fmt].str;
12374 /* Some (all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in
12375 * StretchRect. Thus use StretchRect to draw the YUV surface onto the screen instead
12376 * of drawPrimitive. */
12377 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
12378 D3DRTYPE_SURFACE, format) != D3D_OK)
12380 skip("%s is not supported.\n", fmt_string);
12381 continue;
12383 if (FAILED(IDirect3D9_CheckDeviceFormatConversion(d3d, 0,
12384 D3DDEVTYPE_HAL, format, desc.Format)))
12386 skip("Driver cannot blit %s surfaces.\n", fmt_string);
12387 continue;
12390 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, width, height, format, D3DPOOL_DEFAULT, &surface, NULL);
12391 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %#x.\n", hr);
12393 for (i = 0; i < sizeof(test_data) / sizeof(test_data[0]); i++)
12395 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
12396 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %#x.\n", hr);
12397 buf = lr.pBits;
12398 chroma_buf = buf + lr.Pitch * height;
12399 if (format == MAKEFOURCC('Y','V','1','2'))
12401 v_buf = chroma_buf;
12402 u_buf = chroma_buf + height / 2 * lr.Pitch/2;
12404 /* Draw the top left quarter of the screen with color1, the rest with color2 */
12405 for (y = 0; y < height; y++)
12407 for (x = 0; x < width; x += 2)
12409 DWORD color = (x < width / 2 && y < height / 2) ? test_data[i].color1 : test_data[i].color2;
12410 BYTE Y = (color >> 16) & 0xff;
12411 BYTE U = (color >> 8) & 0xff;
12412 BYTE V = (color >> 0) & 0xff;
12413 if (format == D3DFMT_UYVY)
12415 buf[y * lr.Pitch + 2 * x + 0] = U;
12416 buf[y * lr.Pitch + 2 * x + 1] = Y;
12417 buf[y * lr.Pitch + 2 * x + 2] = V;
12418 buf[y * lr.Pitch + 2 * x + 3] = Y;
12420 else if (format == D3DFMT_YUY2)
12422 buf[y * lr.Pitch + 2 * x + 0] = Y;
12423 buf[y * lr.Pitch + 2 * x + 1] = U;
12424 buf[y * lr.Pitch + 2 * x + 2] = Y;
12425 buf[y * lr.Pitch + 2 * x + 3] = V;
12427 else if (format == MAKEFOURCC('Y','V','1','2'))
12429 buf[y * lr.Pitch + x + 0] = Y;
12430 buf[y * lr.Pitch + x + 1] = Y;
12431 u_buf[(y / 2) * (lr.Pitch / 2) + (x / 2)] = U;
12432 v_buf[(y / 2) * (lr.Pitch / 2) + (x / 2)] = V;
12434 else if (format == MAKEFOURCC('N','V','1','2'))
12436 buf[y * lr.Pitch + x + 0] = Y;
12437 buf[y * lr.Pitch + x + 1] = Y;
12438 chroma_buf[(y / 2) * lr.Pitch + 2 * (x / 2) + 0] = U;
12439 chroma_buf[(y / 2) * lr.Pitch + 2 * (x / 2) + 1] = V;
12443 hr = IDirect3DSurface9_UnlockRect(surface);
12444 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %#x.\n", hr);
12446 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
12447 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %#x.\n", hr);
12448 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
12449 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %#x.\n", hr);
12451 /* Some Windows drivers (mostly Nvidia, but also some VM drivers) insist on doing linear filtering
12452 * although we asked for point filtering. To prevent running into precision problems, read at points
12453 * with some margin within each quadrant.
12455 * Unfortunately different implementations(Windows-Nvidia and Mac-AMD tested) interpret some colors
12456 * vastly differently, so we need a max diff of 18. */
12457 for (y = 0; y < 4; y++)
12459 for (x = 0; x < 4; x++)
12461 UINT xcoord = (1 + 2 * x) * 640 / 8;
12462 UINT ycoord = (1 + 2 * y) * 480 / 8;
12463 ref_color = (y < 2 && x < 2) ? test_data[i].rgb1 : test_data[i].rgb2;
12464 color = getPixelColor(device, xcoord, ycoord);
12465 ok(color_match(color, ref_color, 18),
12466 "Format %s: Got color %#x for pixel (%d/%d)/(%d/%d), pixel %d %d, expected %#x.\n",
12467 fmt_string, color, x, 4, y, 4, xcoord, ycoord, ref_color);
12470 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12472 ok(SUCCEEDED(hr), "Present failed with %#x.\n", hr);
12474 IDirect3DSurface9_Release(surface);
12477 IDirect3DSurface9_Release(target);
12478 refcount = IDirect3DDevice9_Release(device);
12479 ok(!refcount, "Device has %u references left.\n", refcount);
12480 done:
12481 IDirect3D9_Release(d3d);
12482 DestroyWindow(window);
12485 static void texop_range_test(void)
12487 IDirect3DTexture9 *texture;
12488 D3DLOCKED_RECT locked_rect;
12489 IDirect3DDevice9 *device;
12490 IDirect3D9 *d3d;
12491 ULONG refcount;
12492 D3DCAPS9 caps;
12493 DWORD color;
12494 HWND window;
12495 HRESULT hr;
12497 static const struct
12499 float x, y, z;
12500 D3DCOLOR diffuse;
12502 quad[] =
12504 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
12505 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
12506 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
12507 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
12510 window = create_window();
12511 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12512 ok(!!d3d, "Failed to create a D3D object.\n");
12513 if (!(device = create_device(d3d, window, window, TRUE)))
12515 skip("Failed to create a D3D device, skipping tests.\n");
12516 goto done;
12519 /* We need ADD and SUBTRACT operations */
12520 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12521 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
12522 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD))
12524 skip("D3DTOP_ADD is not supported, skipping value range test.\n");
12525 IDirect3DDevice9_Release(device);
12526 goto done;
12528 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT))
12530 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test.\n");
12531 IDirect3DDevice9_Release(device);
12532 goto done;
12535 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12536 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
12537 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12538 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
12539 /* Stage 1: result = diffuse(=1.0) + diffuse
12540 * stage 2: result = result - tfactor(= 0.5)
12542 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12543 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12544 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
12545 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12546 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
12547 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12548 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
12549 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12550 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
12551 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12552 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12553 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12554 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
12555 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12557 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12558 ok(SUCCEEDED(hr), "Failed to clear device, hr %#x.\n\n", hr);
12559 hr = IDirect3DDevice9_BeginScene(device);
12560 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
12561 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12562 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
12563 hr = IDirect3DDevice9_EndScene(device);
12564 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
12566 color = getPixelColor(device, 320, 240);
12567 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
12568 color);
12569 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12570 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12572 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
12573 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
12574 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
12575 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
12576 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
12577 hr = IDirect3DTexture9_UnlockRect(texture, 0);
12578 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
12579 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
12580 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
12582 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
12583 * stage 2: result = result + diffuse(1.0)
12585 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12586 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12587 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12588 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12589 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12590 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12591 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
12592 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12593 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
12594 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12595 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
12596 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12597 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
12598 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12600 hr = IDirect3DDevice9_BeginScene(device);
12601 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
12602 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12603 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
12604 hr = IDirect3DDevice9_EndScene(device);
12605 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
12607 color = getPixelColor(device, 320, 240);
12608 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
12609 color);
12610 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12611 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12613 IDirect3DTexture9_Release(texture);
12614 refcount = IDirect3DDevice9_Release(device);
12615 ok(!refcount, "Device has %u references left.\n", refcount);
12616 done:
12617 IDirect3D9_Release(d3d);
12618 DestroyWindow(window);
12621 static void alphareplicate_test(void)
12623 IDirect3DDevice9 *device;
12624 IDirect3D9 *d3d;
12625 ULONG refcount;
12626 DWORD color;
12627 HWND window;
12628 HRESULT hr;
12630 static const struct
12632 struct vec3 position;
12633 DWORD diffuse;
12635 quad[] =
12637 {{-1.0f, -1.0f, 0.1f}, 0x80ff00ff},
12638 {{-1.0f, 1.0f, 0.1f}, 0x80ff00ff},
12639 {{ 1.0f, -1.0f, 0.1f}, 0x80ff00ff},
12640 {{ 1.0f, 1.0f, 0.1f}, 0x80ff00ff},
12643 window = create_window();
12644 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12645 ok(!!d3d, "Failed to create a D3D object.\n");
12646 if (!(device = create_device(d3d, window, window, TRUE)))
12648 skip("Failed to create a D3D device, skipping tests.\n");
12649 goto done;
12652 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12653 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12655 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12656 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12658 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12659 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12660 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
12661 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12663 hr = IDirect3DDevice9_BeginScene(device);
12664 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12665 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12666 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12667 hr = IDirect3DDevice9_EndScene(device);
12668 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12670 color = getPixelColor(device, 320, 240);
12671 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
12672 color);
12673 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12674 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12676 refcount = IDirect3DDevice9_Release(device);
12677 ok(!refcount, "Device has %u references left.\n", refcount);
12678 done:
12679 IDirect3D9_Release(d3d);
12680 DestroyWindow(window);
12683 static void dp3_alpha_test(void)
12685 IDirect3DDevice9 *device;
12686 IDirect3D9 *d3d;
12687 ULONG refcount;
12688 D3DCAPS9 caps;
12689 DWORD color;
12690 HWND window;
12691 HRESULT hr;
12693 static const struct
12695 struct vec3 position;
12696 DWORD diffuse;
12698 quad[] =
12700 {{-1.0f, -1.0f, 0.1f}, 0x408080c0},
12701 {{-1.0f, 1.0f, 0.1f}, 0x408080c0},
12702 {{ 1.0f, -1.0f, 0.1f}, 0x408080c0},
12703 {{ 1.0f, 1.0f, 0.1f}, 0x408080c0},
12706 window = create_window();
12707 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12708 ok(!!d3d, "Failed to create a D3D object.\n");
12709 if (!(device = create_device(d3d, window, window, TRUE)))
12711 skip("Failed to create a D3D device, skipping tests.\n");
12712 goto done;
12715 memset(&caps, 0, sizeof(caps));
12716 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12717 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
12718 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3))
12720 skip("D3DTOP_DOTPRODUCT3 not supported\n");
12721 IDirect3DDevice9_Release(device);
12722 goto done;
12725 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12726 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12728 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12729 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12731 /* dp3_x4 r0, diffuse_bias, tfactor_bias
12732 * mov r0.a, diffuse.a
12733 * mov r0, r0.a
12735 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
12736 * 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
12737 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
12739 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
12740 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12741 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
12742 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12743 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12744 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12745 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
12746 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12747 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
12748 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12749 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12750 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12751 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
12752 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12753 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
12754 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12755 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
12756 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12757 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12758 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
12760 hr = IDirect3DDevice9_BeginScene(device);
12761 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12762 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12763 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12764 hr = IDirect3DDevice9_EndScene(device);
12765 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12767 color = getPixelColor(device, 320, 240);
12768 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
12769 color);
12770 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12771 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12773 refcount = IDirect3DDevice9_Release(device);
12774 ok(!refcount, "Device has %u references left.\n", refcount);
12775 done:
12776 IDirect3D9_Release(d3d);
12777 DestroyWindow(window);
12780 static void zwriteenable_test(void)
12782 IDirect3DDevice9 *device;
12783 IDirect3D9 *d3d;
12784 D3DCOLOR color;
12785 ULONG refcount;
12786 HWND window;
12787 HRESULT hr;
12789 static const struct
12791 struct vec3 position;
12792 DWORD diffuse;
12794 quad1[] =
12796 {{-1.0f, -1.0f, 0.1f}, 0x00ff0000},
12797 {{-1.0f, 1.0f, 0.1f}, 0x00ff0000},
12798 {{ 1.0f, -1.0f, 0.1f}, 0x00ff0000},
12799 {{ 1.0f, 1.0f, 0.1f}, 0x00ff0000},
12801 quad2[] =
12803 {{-1.0f, -1.0f, 0.9f}, 0x0000ff00},
12804 {{-1.0f, 1.0f, 0.9f}, 0x0000ff00},
12805 {{ 1.0f, -1.0f, 0.9f}, 0x0000ff00},
12806 {{ 1.0f, 1.0f, 0.9f}, 0x0000ff00},
12809 window = create_window();
12810 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12811 ok(!!d3d, "Failed to create a D3D object.\n");
12812 if (!(device = create_device(d3d, window, window, TRUE)))
12814 skip("Failed to create a D3D device, skipping tests.\n");
12815 goto done;
12818 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
12819 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12821 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12822 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12823 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12824 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12825 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12826 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12827 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
12828 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12829 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12830 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
12832 hr = IDirect3DDevice9_BeginScene(device);
12833 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12834 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1,
12835 * zenable = D3DZB_FALSE, zwriteenable = TRUE. The red color is written
12836 * because the z test is disabled. The question is whether the z = 0.1
12837 * values are written into the Z buffer. After the draw, set
12838 * zenable = TRUE and draw a green quad at z = 0.9. If the values are
12839 * written, the z test will fail(0.9 > 0.1) and the red color remains. If
12840 * the values are not written, the z test succeeds(0.9 < 1.0) and the
12841 * green color is written. It turns out that the screen is green, so
12842 * zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z
12843 * buffer. */
12844 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
12845 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12846 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12847 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
12848 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
12849 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12850 hr = IDirect3DDevice9_EndScene(device);
12851 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12853 color = getPixelColor(device, 320, 240);
12854 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
12855 color);
12856 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12857 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12859 refcount = IDirect3DDevice9_Release(device);
12860 ok(!refcount, "Device has %u references left.\n", refcount);
12861 done:
12862 IDirect3D9_Release(d3d);
12863 DestroyWindow(window);
12866 static void alphatest_test(void)
12868 #define ALPHATEST_PASSED 0x0000ff00
12869 #define ALPHATEST_FAILED 0x00ff0000
12870 IDirect3DDevice9 *device;
12871 unsigned int i, j;
12872 IDirect3D9 *d3d;
12873 D3DCOLOR color;
12874 ULONG refcount;
12875 D3DCAPS9 caps;
12876 HWND window;
12877 HRESULT hr;
12879 static const struct
12881 D3DCMPFUNC func;
12882 D3DCOLOR color_less;
12883 D3DCOLOR color_equal;
12884 D3DCOLOR color_greater;
12886 testdata[] =
12888 {D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED},
12889 {D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED},
12890 {D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED},
12891 {D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED},
12892 {D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED},
12893 {D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED},
12894 {D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED},
12895 {D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED},
12897 static const struct
12899 struct vec3 position;
12900 DWORD diffuse;
12902 quad[] =
12904 {{-1.0f, -1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
12905 {{-1.0f, 1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
12906 {{ 1.0f, -1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
12907 {{ 1.0f, 1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
12910 window = create_window();
12911 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12912 ok(!!d3d, "Failed to create a D3D object.\n");
12913 if (!(device = create_device(d3d, window, window, TRUE)))
12915 skip("Failed to create a D3D device, skipping tests.\n");
12916 goto done;
12919 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
12920 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
12922 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12923 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
12924 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
12925 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12926 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12927 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12929 for (j = 0; j < 2; ++j)
12931 if (j == 1)
12933 /* Try a pixel shader instead of fixed function. The wined3d code
12934 * may emulate the alpha test either for performance reasons
12935 * (floating point RTs) or to work around driver bugs (GeForce
12936 * 7x00 cards on MacOS). There may be a different codepath for ffp
12937 * and shader in this case, and the test should cover both. */
12938 IDirect3DPixelShader9 *ps;
12939 static const DWORD shader_code[] =
12941 0xffff0101, /* ps_1_1 */
12942 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
12943 0x0000ffff /* end */
12945 memset(&caps, 0, sizeof(caps));
12946 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12947 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
12948 if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
12949 break;
12952 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
12953 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
12954 hr = IDirect3DDevice9_SetPixelShader(device, ps);
12955 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
12956 IDirect3DPixelShader9_Release(ps);
12959 for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
12960 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
12961 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12963 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
12964 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12965 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
12966 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12967 hr = IDirect3DDevice9_BeginScene(device);
12968 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12969 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12970 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12971 hr = IDirect3DDevice9_EndScene(device);
12972 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12973 color = getPixelColor(device, 320, 240);
12974 ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
12975 color, testdata[i].color_less, testdata[i].func);
12976 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12977 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12979 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
12980 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12981 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
12982 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12983 hr = IDirect3DDevice9_BeginScene(device);
12984 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12985 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12986 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12987 hr = IDirect3DDevice9_EndScene(device);
12988 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12989 color = getPixelColor(device, 320, 240);
12990 ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
12991 color, testdata[i].color_equal, testdata[i].func);
12992 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12993 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12995 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
12996 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12997 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
12998 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12999 hr = IDirect3DDevice9_BeginScene(device);
13000 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13001 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13002 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13003 hr = IDirect3DDevice9_EndScene(device);
13004 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13005 color = getPixelColor(device, 320, 240);
13006 ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
13007 color, testdata[i].color_greater, testdata[i].func);
13008 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13009 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
13013 refcount = IDirect3DDevice9_Release(device);
13014 ok(!refcount, "Device has %u references left.\n", refcount);
13015 done:
13016 IDirect3D9_Release(d3d);
13017 DestroyWindow(window);
13020 static void sincos_test(void)
13022 IDirect3DVertexShader9 *sin_shader, *cos_shader;
13023 IDirect3DDevice9 *device;
13024 struct vec3 data[1280];
13025 IDirect3D9 *d3d;
13026 unsigned int i;
13027 ULONG refcount;
13028 D3DCAPS9 caps;
13029 HWND window;
13030 HRESULT hr;
13032 static const DWORD sin_shader_code[] =
13034 0xfffe0200, /* vs_2_0 */
13035 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
13036 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
13037 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
13038 0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.y, r1.x, c0, c1 */
13039 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
13040 0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002, /* mul oPos.y, r0.y, c2.w */
13041 0x02000001, 0xd00f0000, 0xa0a60002, /* mov oD0, c2.zyzz */
13042 0x0000ffff /* end */
13044 static const DWORD cos_shader_code[] =
13046 0xfffe0200, /* vs_2_0 */
13047 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
13048 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
13049 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
13050 0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.x, r1.x, c0, c1 */
13051 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
13052 0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002, /* mul oPos.y, r0.x, c2.w */
13053 0x02000001, 0xd00f0000, 0xa0a90002, /* mov oD0, c2.yzzz */
13054 0x0000ffff /* end */
13056 static const float sincosc1[4] = {D3DSINCOSCONST1};
13057 static const float sincosc2[4] = {D3DSINCOSCONST2};
13059 window = create_window();
13060 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13061 ok(!!d3d, "Failed to create a D3D object.\n");
13062 if (!(device = create_device(d3d, window, window, TRUE)))
13064 skip("Failed to create a D3D device, skipping tests.\n");
13065 goto done;
13068 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13069 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13070 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
13072 skip("No vs_2_0 support, skipping tests.\n");
13073 IDirect3DDevice9_Release(device);
13074 goto done;
13077 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
13078 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
13080 hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
13081 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
13082 hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
13083 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
13084 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13085 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
13086 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
13087 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
13088 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
13089 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
13091 /* Generate a point from -1 to 1 every 0.5 pixels */
13092 for(i = 0; i < 1280; i++) {
13093 data[i].x = (-640.0 + i) / 640.0;
13094 data[i].y = 0.0;
13095 data[i].z = 0.1;
13098 hr = IDirect3DDevice9_BeginScene(device);
13099 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13101 hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
13102 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
13103 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
13104 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13106 hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
13107 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
13108 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
13109 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13111 hr = IDirect3DDevice9_EndScene(device);
13112 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13114 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13115 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
13116 /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
13118 IDirect3DVertexShader9_Release(sin_shader);
13119 IDirect3DVertexShader9_Release(cos_shader);
13120 refcount = IDirect3DDevice9_Release(device);
13121 ok(!refcount, "Device has %u references left.\n", refcount);
13122 done:
13123 IDirect3D9_Release(d3d);
13124 DestroyWindow(window);
13127 static void loop_index_test(void)
13129 IDirect3DVertexShader9 *shader;
13130 IDirect3DDevice9 *device;
13131 IDirect3D9 *d3d;
13132 float values[4];
13133 ULONG refcount;
13134 D3DCAPS9 caps;
13135 DWORD color;
13136 HWND window;
13137 HRESULT hr;
13139 static const DWORD shader_code[] =
13141 0xfffe0200, /* vs_2_0 */
13142 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
13143 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
13144 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
13145 0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1] */
13146 0x0000001d, /* endloop */
13147 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
13148 0x02000001, 0xd00f0000, 0x80e40000, /* mov oD0, r0 */
13149 0x0000ffff /* END */
13151 static const float quad[] =
13153 -1.0f, -1.0f, 0.1f,
13154 -1.0f, 1.0f, 0.1f,
13155 1.0f, -1.0f, 0.1f,
13156 1.0f, 1.0f, 0.1f,
13158 static const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
13159 static const float one[4] = {1.0f, 1.0f, 1.0f, 1.0f};
13160 static const int i0[4] = {2, 10, -3, 0};
13162 window = create_window();
13163 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13164 ok(!!d3d, "Failed to create a D3D object.\n");
13165 if (!(device = create_device(d3d, window, window, TRUE)))
13167 skip("Failed to create a D3D device, skipping tests.\n");
13168 goto done;
13171 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13172 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13173 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
13175 skip("No vs_2_0 support, skipping tests.\n");
13176 IDirect3DDevice9_Release(device);
13177 goto done;
13180 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
13181 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
13182 hr = IDirect3DDevice9_SetVertexShader(device, shader);
13183 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
13184 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13185 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
13186 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
13187 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
13189 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
13190 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13191 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
13192 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13193 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
13194 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13195 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
13196 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13197 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
13198 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13199 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
13200 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13201 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
13202 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13203 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
13204 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13205 values[0] = 1.0;
13206 values[1] = 1.0;
13207 values[2] = 0.0;
13208 values[3] = 0.0;
13209 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
13210 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13211 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
13212 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13213 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
13214 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13215 values[0] = -1.0;
13216 values[1] = 0.0;
13217 values[2] = 0.0;
13218 values[3] = 0.0;
13219 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
13220 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13221 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
13222 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13223 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
13224 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13225 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
13226 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13227 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
13228 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13230 hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
13231 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
13233 hr = IDirect3DDevice9_BeginScene(device);
13234 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13235 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
13236 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13237 hr = IDirect3DDevice9_EndScene(device);
13238 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13239 color = getPixelColor(device, 320, 240);
13240 ok(color_match(color, 0x0000ff00, 1),
13241 "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
13242 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13243 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
13245 IDirect3DVertexShader9_Release(shader);
13246 refcount = IDirect3DDevice9_Release(device);
13247 ok(!refcount, "Device has %u references left.\n", refcount);
13248 done:
13249 IDirect3D9_Release(d3d);
13250 DestroyWindow(window);
13253 static void sgn_test(void)
13255 IDirect3DVertexShader9 *shader;
13256 IDirect3DDevice9 *device;
13257 IDirect3D9 *d3d;
13258 ULONG refcount;
13259 D3DCAPS9 caps;
13260 DWORD color;
13261 HWND window;
13262 HRESULT hr;
13264 static const DWORD shader_code[] =
13266 0xfffe0200, /* vs_2_0 */
13267 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position o0 */
13268 0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
13269 0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0 */
13270 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
13271 0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002, /* sgn r0, c0, r1, r2 */
13272 0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001, /* add oD0, r0, c1 */
13273 0x0000ffff /* end */
13275 static const float quad[] =
13277 -1.0f, -1.0f, 0.1f,
13278 -1.0f, 1.0f, 0.1f,
13279 1.0f, -1.0f, 0.1f,
13280 1.0f, 1.0f, 0.1f,
13283 window = create_window();
13284 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13285 ok(!!d3d, "Failed to create a D3D object.\n");
13286 if (!(device = create_device(d3d, window, window, TRUE)))
13288 skip("Failed to create a D3D device, skipping tests.\n");
13289 goto done;
13292 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13293 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13294 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
13296 skip("No vs_2_0 support, skipping tests.\n");
13297 IDirect3DDevice9_Release(device);
13298 goto done;
13301 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
13302 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
13303 hr = IDirect3DDevice9_SetVertexShader(device, shader);
13304 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
13305 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13306 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
13307 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
13308 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
13310 hr = IDirect3DDevice9_BeginScene(device);
13311 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13312 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
13313 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13314 hr = IDirect3DDevice9_EndScene(device);
13315 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13316 color = getPixelColor(device, 320, 240);
13317 ok(color_match(color, 0x008000ff, 1),
13318 "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
13319 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13320 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
13322 IDirect3DVertexShader9_Release(shader);
13323 refcount = IDirect3DDevice9_Release(device);
13324 ok(!refcount, "Device has %u references left.\n", refcount);
13325 done:
13326 IDirect3D9_Release(d3d);
13327 DestroyWindow(window);
13330 static void viewport_test(void)
13332 IDirect3DDevice9 *device;
13333 BOOL draw_failed = TRUE;
13334 D3DVIEWPORT9 vp;
13335 IDirect3D9 *d3d;
13336 ULONG refcount;
13337 DWORD color;
13338 HWND window;
13339 HRESULT hr;
13341 static const float quad[] =
13343 -0.5f, -0.5f, 0.1f,
13344 -0.5f, 0.5f, 0.1f,
13345 0.5f, -0.5f, 0.1f,
13346 0.5f, 0.5f, 0.1f,
13349 window = create_window();
13350 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13351 ok(!!d3d, "Failed to create a D3D object.\n");
13352 if (!(device = create_device(d3d, window, window, TRUE)))
13354 skip("Failed to create a D3D device, skipping tests.\n");
13355 goto done;
13358 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
13359 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
13361 /* Test a viewport with Width and Height bigger than the surface dimensions
13363 * TODO: Test Width < surface.width, but X + Width > surface.width
13364 * TODO: Test Width < surface.width, what happens with the height?
13366 * The expected behavior is that the viewport behaves like the "default"
13367 * viewport with X = Y = 0, Width = surface_width, Height = surface_height,
13368 * MinZ = 0.0, MaxZ = 1.0.
13370 * Starting with Windows 7 the behavior among driver versions is not
13371 * consistent. The SetViewport call is accepted on all drivers. Some
13372 * drivers(older nvidia ones) refuse to draw and return an error. Newer
13373 * nvidia drivers draw, but use the actual values in the viewport and only
13374 * display the upper left part on the surface.
13376 memset(&vp, 0, sizeof(vp));
13377 vp.X = 0;
13378 vp.Y = 0;
13379 vp.Width = 10000;
13380 vp.Height = 10000;
13381 vp.MinZ = 0.0;
13382 vp.MaxZ = 0.0;
13383 hr = IDirect3DDevice9_SetViewport(device, &vp);
13384 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
13386 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13387 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
13389 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13390 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
13391 hr = IDirect3DDevice9_BeginScene(device);
13392 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13393 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
13394 ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
13395 draw_failed = FAILED(hr);
13396 hr = IDirect3DDevice9_EndScene(device);
13397 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13399 if(!draw_failed)
13401 color = getPixelColor(device, 158, 118);
13402 ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
13403 color = getPixelColor(device, 162, 118);
13404 ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
13405 color = getPixelColor(device, 158, 122);
13406 ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
13407 color = getPixelColor(device, 162, 122);
13408 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (162,122) has color %08x\n", color);
13410 color = getPixelColor(device, 478, 358);
13411 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (478,358 has color %08x\n", color);
13412 color = getPixelColor(device, 482, 358);
13413 ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
13414 color = getPixelColor(device, 478, 362);
13415 ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
13416 color = getPixelColor(device, 482, 362);
13417 ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
13420 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13421 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
13423 refcount = IDirect3DDevice9_Release(device);
13424 ok(!refcount, "Device has %u references left.\n", refcount);
13425 done:
13426 IDirect3D9_Release(d3d);
13427 DestroyWindow(window);
13430 /* This test tests depth clamping / clipping behaviour:
13431 * - With software vertex processing, depth values are clamped to the
13432 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
13433 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
13434 * same as regular vertices here.
13435 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
13436 * Normal vertices are always clipped. Pretransformed vertices are
13437 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
13438 * - The viewport's MinZ/MaxZ is irrelevant for this.
13440 static void depth_clamp_test(void)
13442 IDirect3DDevice9 *device;
13443 D3DVIEWPORT9 vp;
13444 IDirect3D9 *d3d;
13445 D3DCOLOR color;
13446 ULONG refcount;
13447 D3DCAPS9 caps;
13448 HWND window;
13449 HRESULT hr;
13451 static const struct
13453 struct vec4 position;
13454 DWORD diffuse;
13456 quad1[] =
13458 {{ 0.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
13459 {{640.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
13460 {{ 0.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
13461 {{640.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
13463 quad2[] =
13465 {{ 0.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
13466 {{640.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
13467 {{ 0.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
13468 {{640.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
13470 quad3[] =
13472 {{112.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
13473 {{208.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
13474 {{112.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
13475 {{208.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
13477 quad4[] =
13479 {{ 42.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
13480 {{112.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
13481 {{ 42.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
13482 {{112.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
13484 static const struct
13486 struct vec3 position;
13487 DWORD diffuse;
13489 quad5[] =
13491 {{-0.5f, 0.5f, 10.0f}, 0xff14f914},
13492 {{ 0.5f, 0.5f, 10.0f}, 0xff14f914},
13493 {{-0.5f, -0.5f, 10.0f}, 0xff14f914},
13494 {{ 0.5f, -0.5f, 10.0f}, 0xff14f914},
13496 quad6[] =
13498 {{-1.0f, 0.5f, 10.0f}, 0xfff91414},
13499 {{ 1.0f, 0.5f, 10.0f}, 0xfff91414},
13500 {{-1.0f, 0.25f, 10.0f}, 0xfff91414},
13501 {{ 1.0f, 0.25f, 10.0f}, 0xfff91414},
13504 window = create_window();
13505 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13506 ok(!!d3d, "Failed to create a D3D object.\n");
13507 if (!(device = create_device(d3d, window, window, TRUE)))
13509 skip("Failed to create a D3D device, skipping tests.\n");
13510 goto done;
13513 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13514 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13516 vp.X = 0;
13517 vp.Y = 0;
13518 vp.Width = 640;
13519 vp.Height = 480;
13520 vp.MinZ = 0.0;
13521 vp.MaxZ = 7.5;
13523 hr = IDirect3DDevice9_SetViewport(device, &vp);
13524 if(FAILED(hr))
13526 /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
13527 * the tests because the 7.5 is just intended to show that it doesn't have
13528 * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
13529 * viewport and continue.
13531 ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
13532 vp.MaxZ = 1.0;
13533 hr = IDirect3DDevice9_SetViewport(device, &vp);
13535 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
13537 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
13538 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13540 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
13541 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13542 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13543 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13544 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13545 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13546 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13547 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13549 hr = IDirect3DDevice9_BeginScene(device);
13550 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13552 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
13553 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13555 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13556 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13557 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13558 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13560 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
13561 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13563 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
13564 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13565 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
13566 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13568 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
13569 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13571 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13572 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13574 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
13575 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13577 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
13578 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13580 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
13581 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13583 hr = IDirect3DDevice9_EndScene(device);
13584 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13586 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
13588 color = getPixelColor(device, 75, 75);
13589 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13590 color = getPixelColor(device, 150, 150);
13591 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13592 color = getPixelColor(device, 320, 240);
13593 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13594 color = getPixelColor(device, 320, 330);
13595 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13596 color = getPixelColor(device, 320, 330);
13597 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13599 else
13601 color = getPixelColor(device, 75, 75);
13602 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
13603 color = getPixelColor(device, 150, 150);
13604 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
13605 color = getPixelColor(device, 320, 240);
13606 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
13607 color = getPixelColor(device, 320, 330);
13608 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13609 color = getPixelColor(device, 320, 330);
13610 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13613 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13614 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13616 refcount = IDirect3DDevice9_Release(device);
13617 ok(!refcount, "Device has %u references left.\n", refcount);
13618 done:
13619 IDirect3D9_Release(d3d);
13620 DestroyWindow(window);
13623 static void depth_bounds_test(void)
13625 static const struct
13627 struct vec4 position;
13628 DWORD diffuse;
13630 quad1[] =
13632 {{ 0.0f, 0.0f, 0.0f, 1.0f}, 0xfff9e814},
13633 {{640.0f, 0.0f, 0.0f, 1.0f}, 0xfff9e814},
13634 {{ 0.0f, 480.0f, 1.0f, 1.0f}, 0xfff9e814},
13635 {{640.0f, 480.0f, 1.0f, 1.0f}, 0xfff9e814},
13637 quad2[] =
13639 {{ 0.0f, 0.0f, 0.6f, 1.0f}, 0xff002b7f},
13640 {{640.0f, 0.0f, 0.6f, 1.0f}, 0xff002b7f},
13641 {{ 0.0f, 480.0f, 0.6f, 1.0f}, 0xff002b7f},
13642 {{640.0f, 480.0f, 0.6f, 1.0f}, 0xff002b7f},
13644 quad3[] =
13646 {{ 0.0f, 100.0f, 0.6f, 1.0f}, 0xfff91414},
13647 {{640.0f, 100.0f, 0.6f, 1.0f}, 0xfff91414},
13648 {{ 0.0f, 160.0f, 0.6f, 1.0f}, 0xfff91414},
13649 {{640.0f, 160.0f, 0.6f, 1.0f}, 0xfff91414},
13652 union {
13653 DWORD d;
13654 float f;
13655 } tmpvalue;
13657 IDirect3DSurface9 *offscreen_surface = NULL;
13658 IDirect3DDevice9 *device;
13659 IDirect3D9 *d3d;
13660 D3DCOLOR color;
13661 ULONG refcount;
13662 HWND window;
13663 HRESULT hr;
13665 window = create_window();
13666 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13667 ok(!!d3d, "Failed to create a D3D object.\n");
13668 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
13669 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK)
13671 skip("No NVDB (depth bounds test) support, skipping tests.\n");
13672 goto done;
13674 if (!(device = create_device(d3d, window, window, TRUE)))
13676 skip("Failed to create a D3D device, skipping tests.\n");
13677 goto done;
13680 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
13681 MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
13682 ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
13683 if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
13685 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
13686 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13688 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13689 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13690 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13691 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13692 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13693 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13694 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13695 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13698 hr = IDirect3DDevice9_BeginScene(device);
13699 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13701 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
13702 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13704 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13705 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13707 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
13708 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13710 tmpvalue.f = 0.625;
13711 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
13712 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13714 tmpvalue.f = 0.75;
13715 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
13716 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13718 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13719 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13721 tmpvalue.f = 0.75;
13722 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
13723 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13725 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
13726 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13728 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
13729 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13731 hr = IDirect3DDevice9_EndScene(device);
13732 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13734 color = getPixelColor(device, 150, 130);
13735 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13736 color = getPixelColor(device, 150, 200);
13737 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13738 color = getPixelColor(device, 150, 300-5);
13739 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13740 color = getPixelColor(device, 150, 300+5);
13741 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
13742 color = getPixelColor(device, 150, 330);
13743 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
13744 color = getPixelColor(device, 150, 360-5);
13745 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
13746 color = getPixelColor(device, 150, 360+5);
13747 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13749 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13750 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13751 refcount = IDirect3DDevice9_Release(device);
13752 ok(!refcount, "Device has %u references left.\n", refcount);
13753 done:
13754 IDirect3D9_Release(d3d);
13755 DestroyWindow(window);
13758 static void depth_buffer_test(void)
13760 static const struct
13762 struct vec3 position;
13763 DWORD diffuse;
13765 quad1[] =
13767 {{-1.0, 1.0, 0.33f}, 0xff00ff00},
13768 {{ 1.0, 1.0, 0.33f}, 0xff00ff00},
13769 {{-1.0, -1.0, 0.33f}, 0xff00ff00},
13770 {{ 1.0, -1.0, 0.33f}, 0xff00ff00},
13772 quad2[] =
13774 {{-1.0, 1.0, 0.50f}, 0xffff00ff},
13775 {{ 1.0, 1.0, 0.50f}, 0xffff00ff},
13776 {{-1.0, -1.0, 0.50f}, 0xffff00ff},
13777 {{ 1.0, -1.0, 0.50f}, 0xffff00ff},
13779 quad3[] =
13781 {{-1.0, 1.0, 0.66f}, 0xffff0000},
13782 {{ 1.0, 1.0, 0.66f}, 0xffff0000},
13783 {{-1.0, -1.0, 0.66f}, 0xffff0000},
13784 {{ 1.0, -1.0, 0.66f}, 0xffff0000},
13786 static const DWORD expected_colors[4][4] =
13788 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
13789 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
13790 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
13791 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
13794 IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
13795 IDirect3DDevice9 *device;
13796 unsigned int i, j;
13797 D3DVIEWPORT9 vp;
13798 IDirect3D9 *d3d;
13799 D3DCOLOR color;
13800 ULONG refcount;
13801 HWND window;
13802 HRESULT hr;
13804 window = create_window();
13805 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13806 ok(!!d3d, "Failed to create a D3D object.\n");
13807 if (!(device = create_device(d3d, window, window, TRUE)))
13809 skip("Failed to create a D3D device, skipping tests.\n");
13810 goto done;
13813 vp.X = 0;
13814 vp.Y = 0;
13815 vp.Width = 640;
13816 vp.Height = 480;
13817 vp.MinZ = 0.0;
13818 vp.MaxZ = 1.0;
13820 hr = IDirect3DDevice9_SetViewport(device, &vp);
13821 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
13823 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13824 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13825 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13826 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13827 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13828 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13829 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13830 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13831 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13832 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13834 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
13835 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
13836 hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
13837 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
13838 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13839 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
13840 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
13841 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13842 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13843 D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
13844 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13846 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
13847 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13848 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
13849 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13851 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
13852 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13853 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
13854 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13856 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
13857 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13858 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
13859 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13861 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
13862 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13863 hr = IDirect3DDevice9_BeginScene(device);
13864 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13865 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13866 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13867 hr = IDirect3DDevice9_EndScene(device);
13868 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13870 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
13871 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13873 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13874 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13876 hr = IDirect3DDevice9_BeginScene(device);
13877 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13878 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13879 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13880 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
13881 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13882 hr = IDirect3DDevice9_EndScene(device);
13883 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13885 for (i = 0; i < 4; ++i)
13887 for (j = 0; j < 4; ++j)
13889 unsigned int x = 80 * ((2 * j) + 1);
13890 unsigned int y = 60 * ((2 * i) + 1);
13891 color = getPixelColor(device, x, y);
13892 ok(color_match(color, expected_colors[i][j], 0),
13893 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
13897 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13898 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13900 IDirect3DSurface9_Release(backbuffer);
13901 IDirect3DSurface9_Release(rt3);
13902 IDirect3DSurface9_Release(rt2);
13903 IDirect3DSurface9_Release(rt1);
13904 refcount = IDirect3DDevice9_Release(device);
13905 ok(!refcount, "Device has %u references left.\n", refcount);
13906 done:
13907 IDirect3D9_Release(d3d);
13908 DestroyWindow(window);
13911 /* Test that partial depth copies work the way they're supposed to. The clear
13912 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
13913 * the following draw should only copy back the part that was modified. */
13914 static void depth_buffer2_test(void)
13916 static const struct
13918 struct vec3 position;
13919 DWORD diffuse;
13921 quad[] =
13923 {{-1.0f, 1.0f, 0.66f}, 0xffff0000},
13924 {{ 1.0f, 1.0f, 0.66f}, 0xffff0000},
13925 {{-1.0f, -1.0f, 0.66f}, 0xffff0000},
13926 {{ 1.0f, -1.0f, 0.66f}, 0xffff0000},
13929 IDirect3DSurface9 *backbuffer, *rt1, *rt2;
13930 IDirect3DDevice9 *device;
13931 unsigned int i, j;
13932 D3DVIEWPORT9 vp;
13933 IDirect3D9 *d3d;
13934 D3DCOLOR color;
13935 ULONG refcount;
13936 HWND window;
13937 HRESULT hr;
13939 window = create_window();
13940 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13941 ok(!!d3d, "Failed to create a D3D object.\n");
13942 if (!(device = create_device(d3d, window, window, TRUE)))
13944 skip("Failed to create a D3D device, skipping tests.\n");
13945 goto done;
13948 vp.X = 0;
13949 vp.Y = 0;
13950 vp.Width = 640;
13951 vp.Height = 480;
13952 vp.MinZ = 0.0;
13953 vp.MaxZ = 1.0;
13955 hr = IDirect3DDevice9_SetViewport(device, &vp);
13956 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
13958 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13959 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13960 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13961 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13962 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13963 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13964 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13965 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13966 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13967 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13969 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13970 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
13971 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13972 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
13973 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
13974 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13975 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
13976 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
13978 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
13979 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13980 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
13981 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13983 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
13984 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13985 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
13986 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13988 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
13989 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13990 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
13991 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13993 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
13994 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13996 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13997 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13999 hr = IDirect3DDevice9_BeginScene(device);
14000 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14001 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14002 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14003 hr = IDirect3DDevice9_EndScene(device);
14004 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14006 for (i = 0; i < 4; ++i)
14008 for (j = 0; j < 4; ++j)
14010 unsigned int x = 80 * ((2 * j) + 1);
14011 unsigned int y = 60 * ((2 * i) + 1);
14012 color = getPixelColor(device, x, y);
14013 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
14014 "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
14018 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14019 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14021 IDirect3DSurface9_Release(backbuffer);
14022 IDirect3DSurface9_Release(rt2);
14023 IDirect3DSurface9_Release(rt1);
14024 refcount = IDirect3DDevice9_Release(device);
14025 ok(!refcount, "Device has %u references left.\n", refcount);
14026 done:
14027 IDirect3D9_Release(d3d);
14028 DestroyWindow(window);
14031 static void depth_blit_test(void)
14033 static const struct
14035 struct vec3 position;
14036 DWORD diffuse;
14038 quad1[] =
14040 {{-1.0f, 1.0f, 0.33f}, 0xff00ff00},
14041 {{ 1.0f, 1.0f, 0.33f}, 0xff00ff00},
14042 {{-1.0f, -1.0f, 0.33f}, 0xff00ff00},
14043 {{ 1.0f, -1.0f, 0.33f}, 0xff00ff00},
14045 quad2[] =
14047 {{-1.0f, 1.0f, 0.66f}, 0xff0000ff},
14048 {{ 1.0f, 1.0f, 0.66f}, 0xff0000ff},
14049 {{-1.0f, -1.0f, 0.66f}, 0xff0000ff},
14050 {{ 1.0f, -1.0f, 0.66f}, 0xff0000ff},
14052 static const DWORD expected_colors[4][4] =
14054 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
14055 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
14056 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
14057 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
14060 IDirect3DSurface9 *backbuffer, *ds1, *ds2, *ds3;
14061 IDirect3DDevice9 *device;
14062 RECT src_rect, dst_rect;
14063 unsigned int i, j;
14064 D3DVIEWPORT9 vp;
14065 IDirect3D9 *d3d;
14066 D3DCOLOR color;
14067 ULONG refcount;
14068 HWND window;
14069 HRESULT hr;
14071 window = create_window();
14072 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14073 ok(!!d3d, "Failed to create a D3D object.\n");
14074 if (!(device = create_device(d3d, window, window, TRUE)))
14076 skip("Failed to create a D3D device, skipping tests.\n");
14077 goto done;
14080 vp.X = 0;
14081 vp.Y = 0;
14082 vp.Width = 640;
14083 vp.Height = 480;
14084 vp.MinZ = 0.0;
14085 vp.MaxZ = 1.0;
14087 hr = IDirect3DDevice9_SetViewport(device, &vp);
14088 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
14090 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
14091 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14092 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
14093 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
14094 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
14095 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
14096 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
14097 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14098 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 320, 240, D3DFMT_D24S8, 0, 0, FALSE, &ds3, NULL);
14099 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
14101 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14102 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14103 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14104 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14105 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
14106 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14107 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
14108 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14110 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14111 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14112 SetRect(&dst_rect, 0, 0, 480, 360);
14113 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
14114 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14115 SetRect(&dst_rect, 0, 0, 320, 240);
14116 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
14117 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14119 /* Partial blit. */
14120 SetRect(&src_rect, 0, 0, 320, 240);
14121 SetRect(&dst_rect, 0, 0, 320, 240);
14122 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
14123 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14124 /* Flipped. */
14125 SetRect(&src_rect, 0, 0, 640, 480);
14126 SetRect(&dst_rect, 0, 480, 640, 0);
14127 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
14128 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14129 /* Full, explicit. */
14130 SetRect(&src_rect, 0, 0, 640, 480);
14131 SetRect(&dst_rect, 0, 0, 640, 480);
14132 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
14133 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14134 /* Filtered blit. */
14135 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
14136 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14137 /* Depth -> color blit.*/
14138 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
14139 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14140 IDirect3DSurface9_Release(backbuffer);
14141 /* Full surface, different sizes */
14142 hr = IDirect3DDevice9_StretchRect(device, ds3, NULL, ds1, NULL, D3DTEXF_POINT);
14143 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14144 hr = IDirect3DDevice9_StretchRect(device, ds1, NULL, ds3, NULL, D3DTEXF_POINT);
14145 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14147 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
14148 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14149 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
14150 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14151 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
14152 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14154 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
14155 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14156 hr = IDirect3DDevice9_BeginScene(device);
14157 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14158 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
14159 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14160 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
14161 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14162 hr = IDirect3DDevice9_EndScene(device);
14163 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14165 for (i = 0; i < 4; ++i)
14167 for (j = 0; j < 4; ++j)
14169 unsigned int x = 80 * ((2 * j) + 1);
14170 unsigned int y = 60 * ((2 * i) + 1);
14171 color = getPixelColor(device, x, y);
14172 ok(color_match(color, expected_colors[i][j], 0),
14173 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
14177 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14178 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14180 IDirect3DSurface9_Release(ds3);
14181 IDirect3DSurface9_Release(ds2);
14182 IDirect3DSurface9_Release(ds1);
14183 refcount = IDirect3DDevice9_Release(device);
14184 ok(!refcount, "Device has %u references left.\n", refcount);
14185 done:
14186 IDirect3D9_Release(d3d);
14187 DestroyWindow(window);
14190 static void intz_test(void)
14192 static const DWORD ps_code[] =
14194 0xffff0200, /* ps_2_0 */
14195 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
14196 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
14197 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
14198 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
14199 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
14200 0x03010042, 0x800f0001, 0xb0e40000, 0xa0e40800, /* texldp r1, t0, s0 */
14201 0x02000001, 0x80020000, 0x80000001, /* mov r0.y, r1.x */
14202 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14203 0x0000ffff, /* end */
14205 struct
14207 float x, y, z;
14208 float s, t, p, q;
14210 quad[] =
14212 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
14213 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
14214 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
14215 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
14217 half_quad_1[] =
14219 { -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
14220 { 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
14221 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
14222 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
14224 half_quad_2[] =
14226 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
14227 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
14228 { -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
14229 { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
14231 struct
14233 UINT x, y;
14234 D3DCOLOR color;
14236 expected_colors[] =
14238 { 80, 100, 0x20204020},
14239 {240, 100, 0x6060bf60},
14240 {400, 100, 0x9f9f409f},
14241 {560, 100, 0xdfdfbfdf},
14242 { 80, 450, 0x20204020},
14243 {240, 450, 0x6060bf60},
14244 {400, 450, 0x9f9f409f},
14245 {560, 450, 0xdfdfbfdf},
14248 IDirect3DSurface9 *original_rt, *rt;
14249 struct surface_readback rb;
14250 IDirect3DTexture9 *texture;
14251 IDirect3DPixelShader9 *ps;
14252 IDirect3DDevice9 *device;
14253 IDirect3DSurface9 *ds;
14254 IDirect3D9 *d3d;
14255 ULONG refcount;
14256 D3DCAPS9 caps;
14257 HWND window;
14258 HRESULT hr;
14259 UINT i;
14261 window = create_window();
14262 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14263 ok(!!d3d, "Failed to create a D3D object.\n");
14264 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
14265 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
14267 skip("No INTZ support, skipping INTZ test.\n");
14268 goto done;
14270 if (!(device = create_device(d3d, window, window, TRUE)))
14272 skip("Failed to create a D3D device, skipping tests.\n");
14273 goto done;
14276 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14277 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
14278 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
14280 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
14281 IDirect3DDevice9_Release(device);
14282 goto done;
14284 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
14286 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
14287 IDirect3DDevice9_Release(device);
14288 goto done;
14291 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14292 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14294 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
14295 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
14296 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
14297 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
14298 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
14299 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
14300 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
14301 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
14303 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
14304 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14305 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14306 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14307 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
14308 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14309 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14310 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14311 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14312 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14314 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
14315 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14316 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
14317 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14318 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
14319 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14320 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
14321 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14322 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
14323 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14325 /* Render offscreen, using the INTZ texture as depth buffer */
14326 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14327 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14328 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14329 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14330 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14331 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14332 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14333 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14335 /* Setup the depth/stencil surface. */
14336 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14337 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14339 hr = IDirect3DDevice9_BeginScene(device);
14340 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14341 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14342 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14343 hr = IDirect3DDevice9_EndScene(device);
14344 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14346 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14347 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14348 IDirect3DSurface9_Release(ds);
14349 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14350 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14351 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14352 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14353 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14354 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14356 /* Read the depth values back. */
14357 hr = IDirect3DDevice9_BeginScene(device);
14358 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14359 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14360 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14361 hr = IDirect3DDevice9_EndScene(device);
14362 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14364 get_rt_readback(original_rt, &rb);
14365 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14367 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
14368 ok(color_match(color, expected_colors[i].color, 1),
14369 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14370 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14372 release_surface_readback(&rb);
14374 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14375 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14377 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14378 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14379 IDirect3DTexture9_Release(texture);
14381 /* Render onscreen while using the INTZ texture as depth buffer */
14382 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
14383 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
14384 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14385 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14386 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14387 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14388 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14389 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14391 /* Setup the depth/stencil surface. */
14392 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14393 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14395 hr = IDirect3DDevice9_BeginScene(device);
14396 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14397 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14398 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14399 hr = IDirect3DDevice9_EndScene(device);
14400 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14402 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14403 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14404 IDirect3DSurface9_Release(ds);
14405 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14406 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14407 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14408 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14410 /* Read the depth values back. */
14411 hr = IDirect3DDevice9_BeginScene(device);
14412 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14413 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14414 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14415 hr = IDirect3DDevice9_EndScene(device);
14416 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14418 get_rt_readback(original_rt, &rb);
14419 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14421 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
14422 ok(color_match(color, expected_colors[i].color, 1),
14423 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14424 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14426 release_surface_readback(&rb);
14428 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14429 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14431 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14432 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14433 IDirect3DTexture9_Release(texture);
14435 /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
14436 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
14437 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
14438 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14439 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14441 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14442 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14443 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14444 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14445 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14446 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14448 /* Setup the depth/stencil surface. */
14449 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14450 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14452 hr = IDirect3DDevice9_BeginScene(device);
14453 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14454 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
14455 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14456 hr = IDirect3DDevice9_EndScene(device);
14457 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14459 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14460 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14462 hr = IDirect3DDevice9_BeginScene(device);
14463 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14464 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
14465 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14466 hr = IDirect3DDevice9_EndScene(device);
14467 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14469 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14470 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14471 IDirect3DSurface9_Release(ds);
14472 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14473 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14474 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14475 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14477 /* Read the depth values back. */
14478 hr = IDirect3DDevice9_BeginScene(device);
14479 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14480 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14481 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14482 hr = IDirect3DDevice9_EndScene(device);
14483 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14485 get_rt_readback(original_rt, &rb);
14486 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14488 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
14489 ok(color_match(color, expected_colors[i].color, 1),
14490 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14491 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14493 release_surface_readback(&rb);
14495 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14496 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14498 IDirect3DTexture9_Release(texture);
14499 IDirect3DPixelShader9_Release(ps);
14500 IDirect3DSurface9_Release(original_rt);
14501 IDirect3DSurface9_Release(rt);
14502 refcount = IDirect3DDevice9_Release(device);
14503 ok(!refcount, "Device has %u references left.\n", refcount);
14504 done:
14505 IDirect3D9_Release(d3d);
14506 DestroyWindow(window);
14509 static void shadow_test(void)
14511 static const DWORD ps_code[] =
14513 0xffff0200, /* ps_2_0 */
14514 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
14515 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
14516 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
14517 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
14518 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
14519 0x03010042, 0x800f0001, 0xb0e40000, 0xa0e40800, /* texldp r1, t0, s0 */
14520 0x02000001, 0x80020000, 0x80000001, /* mov r0.y, r1.x */
14521 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14522 0x0000ffff, /* end */
14524 struct
14526 D3DFORMAT format;
14527 const char *name;
14529 formats[] =
14531 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
14532 {D3DFMT_D32, "D3DFMT_D32"},
14533 {D3DFMT_D15S1, "D3DFMT_D15S1"},
14534 {D3DFMT_D24S8, "D3DFMT_D24S8"},
14535 {D3DFMT_D24X8, "D3DFMT_D24X8"},
14536 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
14537 {D3DFMT_D16, "D3DFMT_D16"},
14538 {D3DFMT_D32F_LOCKABLE, "D3DFMT_D32F_LOCKABLE"},
14539 {D3DFMT_D24FS8, "D3DFMT_D24FS8"},
14541 struct
14543 float x, y, z;
14544 float s, t, p, q;
14546 quad[] =
14548 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
14549 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
14550 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
14551 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
14553 struct
14555 UINT x, y;
14556 D3DCOLOR color;
14558 expected_colors[] =
14560 {400, 60, 0x00000000},
14561 {560, 180, 0xffff00ff},
14562 {560, 300, 0xffff00ff},
14563 {400, 420, 0xffffffff},
14564 {240, 420, 0xffffffff},
14565 { 80, 300, 0x00000000},
14566 { 80, 180, 0x00000000},
14567 {240, 60, 0x00000000},
14570 IDirect3DSurface9 *original_ds, *original_rt, *rt;
14571 struct surface_readback rb;
14572 IDirect3DPixelShader9 *ps;
14573 IDirect3DDevice9 *device;
14574 IDirect3D9 *d3d;
14575 ULONG refcount;
14576 D3DCAPS9 caps;
14577 HWND window;
14578 HRESULT hr;
14579 UINT i;
14581 window = create_window();
14582 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14583 ok(!!d3d, "Failed to create a D3D object.\n");
14584 if (!(device = create_device(d3d, window, window, TRUE)))
14586 skip("Failed to create a D3D device, skipping tests.\n");
14587 goto done;
14590 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14591 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
14592 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
14594 skip("No pixel shader 2.0 support, skipping shadow test.\n");
14595 IDirect3DDevice9_Release(device);
14596 goto done;
14599 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14600 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14601 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
14602 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
14604 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
14605 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
14606 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
14607 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
14608 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
14610 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
14611 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14612 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14613 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14614 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
14615 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14616 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14617 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14618 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14619 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14621 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
14622 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14623 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
14624 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14625 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
14626 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14627 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
14628 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14629 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
14630 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14632 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
14634 D3DFORMAT format = formats[i].format;
14635 IDirect3DTexture9 *texture;
14636 IDirect3DSurface9 *ds;
14637 unsigned int j;
14639 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
14640 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format)))
14641 continue;
14643 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
14644 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
14645 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
14647 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14648 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14650 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14651 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14653 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14654 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14656 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14657 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14659 /* Setup the depth/stencil surface. */
14660 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14661 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14663 hr = IDirect3DDevice9_BeginScene(device);
14664 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14665 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14666 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14667 hr = IDirect3DDevice9_EndScene(device);
14668 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14670 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14671 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14672 IDirect3DSurface9_Release(ds);
14674 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14675 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14677 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14678 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14680 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14681 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14683 /* Do the actual shadow mapping. */
14684 hr = IDirect3DDevice9_BeginScene(device);
14685 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14686 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14687 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14688 hr = IDirect3DDevice9_EndScene(device);
14689 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14691 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14692 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14693 IDirect3DTexture9_Release(texture);
14695 get_rt_readback(original_rt, &rb);
14696 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
14698 D3DCOLOR color = get_readback_color(&rb, expected_colors[j].x, expected_colors[j].y);
14699 /* Geforce 7 on Windows returns 1.0 in alpha when the depth format is D24S8 or D24X8,
14700 * whereas other GPUs (all AMD, newer Nvidia) return the same value they return in .rgb.
14701 * Accept alpha mismatches as broken but make sure to check the color channels. */
14702 ok(color_match(color, expected_colors[j].color, 0)
14703 || broken(color_match(color & 0x00ffffff, expected_colors[j].color & 0x00ffffff, 0)),
14704 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
14705 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
14706 formats[i].name, color);
14708 release_surface_readback(&rb);
14710 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14711 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14714 IDirect3DPixelShader9_Release(ps);
14715 IDirect3DSurface9_Release(original_ds);
14716 IDirect3DSurface9_Release(original_rt);
14717 IDirect3DSurface9_Release(rt);
14718 refcount = IDirect3DDevice9_Release(device);
14719 ok(!refcount, "Device has %u references left.\n", refcount);
14720 done:
14721 IDirect3D9_Release(d3d);
14722 DestroyWindow(window);
14725 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
14727 static const struct
14729 struct vec3 position;
14730 DWORD diffuse;
14732 quad1[] =
14734 {{-1.0f, -1.0f, 0.0f}, 0xfff9e814},
14735 {{-1.0f, 1.0f, 0.0f}, 0xfff9e814},
14736 {{ 1.0f, -1.0f, 0.0f}, 0xfff9e814},
14737 {{ 1.0f, 1.0f, 0.0f}, 0xfff9e814},
14739 quad2[] =
14741 {{-1.0f, -1.0f, 0.0f}, 0xff002b7f},
14742 {{-1.0f, 1.0f, 0.0f}, 0xff002b7f},
14743 {{ 1.0f, -1.0f, 0.0f}, 0xff002b7f},
14744 {{ 1.0f, 1.0f, 0.0f}, 0xff002b7f},
14746 D3DCOLOR color;
14747 HRESULT hr;
14749 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
14750 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14752 hr = IDirect3DDevice9_BeginScene(device);
14753 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14755 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
14756 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14758 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
14759 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14760 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
14761 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14763 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
14764 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14765 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
14766 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14768 hr = IDirect3DDevice9_EndScene(device);
14769 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14771 color = getPixelColor(device, 1, 240);
14772 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
14773 color = getPixelColor(device, 638, 240);
14774 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
14776 color = getPixelColor(device, 1, 241);
14777 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
14778 color = getPixelColor(device, 638, 241);
14779 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
14782 static void clip_planes_test(void)
14784 IDirect3DSurface9 *offscreen_surface, *original_rt;
14785 IDirect3DTexture9 *offscreen = NULL;
14786 IDirect3DVertexShader9 *shader;
14787 IDirect3DDevice9 *device;
14788 IDirect3D9 *d3d;
14789 ULONG refcount;
14790 D3DCAPS9 caps;
14791 HWND window;
14792 HRESULT hr;
14794 static const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
14795 static const DWORD shader_code[] =
14797 0xfffe0200, /* vs_2_0 */
14798 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
14799 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
14800 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
14801 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
14802 0x0000ffff /* end */
14805 window = create_window();
14806 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14807 ok(!!d3d, "Failed to create a D3D object.\n");
14808 if (!(device = create_device(d3d, window, window, TRUE)))
14810 skip("Failed to create a D3D device, skipping tests.\n");
14811 goto done;
14814 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14815 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
14816 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
14818 skip("No vs_2_0 support, skipping tests.\n");
14819 IDirect3DDevice9_Release(device);
14820 goto done;
14823 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14824 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14826 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14827 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14828 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
14829 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14830 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
14831 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14832 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
14833 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14835 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
14836 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
14837 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14838 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
14840 IDirect3DDevice9_SetClipPlane(device, 0, plane0);
14842 clip_planes(device, "Onscreen FFP");
14844 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
14845 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
14846 hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
14847 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14848 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
14849 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
14851 clip_planes(device, "Offscreen FFP");
14853 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14854 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14856 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
14857 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
14858 hr = IDirect3DDevice9_SetVertexShader(device, shader);
14859 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
14861 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14862 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
14864 clip_planes(device, "Onscreen vertex shader");
14866 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
14867 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
14869 clip_planes(device, "Offscreen vertex shader");
14871 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14872 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14874 IDirect3DVertexShader9_Release(shader);
14875 IDirect3DSurface9_Release(original_rt);
14876 IDirect3DSurface9_Release(offscreen_surface);
14877 IDirect3DTexture9_Release(offscreen);
14878 refcount = IDirect3DDevice9_Release(device);
14879 ok(!refcount, "Device has %u references left.\n", refcount);
14880 done:
14881 IDirect3D9_Release(d3d);
14882 DestroyWindow(window);
14885 static void fp_special_test(void)
14887 /* Microsoft's assembler generates nan and inf with "1.#QNAN" and "1.#INF." respectively */
14888 static const DWORD vs_header[] =
14890 0xfffe0200, /* vs_2_0 */
14891 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
14892 0x05000051, 0xa00f0001, 0x7fc00000, 0xff800000, 0x7f800000, 0x00000000, /* def c1, nan, -inf, inf, 0 */
14893 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
14894 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
14897 static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001}; /* log r0.x, v1.x */
14898 static const DWORD vs_pow[] =
14899 {0x03000020, 0x80010000, 0x90000001, 0x90000001}; /* pow r0.x, v1.x, v1.x */
14900 static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001}; /* nrm r0.xyz, v1.x */
14901 static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001}; /* rcp r0.x, v1.x */
14902 static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001}; /* rcp r0.x, -v1.x */
14903 static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001}; /* rsq r0.x, v1.x */
14904 static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001}; /* rsq r0.x, -v1.x */
14905 static const DWORD vs_lit[] = {0x02000010, 0x800f0000, 0x90000001, /* lit r0, v1.xxxx */
14906 0x02000001, 0x80010000, 0x80aa0000}; /* mov r0.x, v0.z */
14907 static const DWORD vs_def1[] = {0x02000001, 0x80010000, 0xa0000001}; /* mov r0.x, c1.x */
14908 static const DWORD vs_def2[] = {0x02000001, 0x80010000, 0xa0550001}; /* mov r0.x, c1.y */
14909 static const DWORD vs_def3[] = {0x02000001, 0x80010000, 0xa0aa0001}; /* mov r0.x, c1.z */
14911 static const DWORD vs_footer[] =
14913 0x03000005, 0x80020000, 0x80000000, 0xa0ff0000, /* mul r0.y, r0.x, c0.w */
14914 0x0300000d, 0x80040000, 0x80000000, 0x80550000, /* sge r0.z, r0.x, r0.y */
14915 0x0300000d, 0x80020000, 0x80e40000, 0x80000000, /* sge r0.y, r0, r0.x */
14916 0x03000005, 0x80040000, 0x80550000, 0x80e40000, /* mul r0.z, r0.y, r0 */
14917 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
14918 0x0300000c, 0x80020000, 0x80000000, 0x80000000, /* slt r0.y, r0.x, r0.x */
14919 0x03000002, 0x80040000, 0x80550000, 0x80550000, /* add r0.z, r0.y, r0.y */
14920 0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000, /* slt r0.y, c0.x, r0.w */
14921 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
14922 0x03000002, 0x80040000, 0x81550000, 0xa0e40000, /* add r0.z, -r0.y, c0 */
14923 0x0300000c, 0x80080000, 0xa0000000, 0x80e40000, /* slt r0.w, c0.x, r0 */
14924 0x03000005, 0x80040000, 0x80ff0000, 0x80e40000, /* mul r0.z, r0.w, r0 */
14925 0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000, /* mad r0.y, r0.z, c0, r0 */
14926 0x02000001, 0xe0030000, 0x80e40000, /* mov oT0.xy, r0 */
14927 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
14928 0x0000ffff, /* end */
14931 static const struct
14933 const char *name;
14934 const DWORD *ops;
14935 DWORD size;
14936 D3DCOLOR r500;
14937 D3DCOLOR r600;
14938 D3DCOLOR nv40;
14939 D3DCOLOR nv50;
14940 D3DCOLOR warp;
14942 vs_body[] =
14944 /* The basic ideas here are:
14945 * 2.0 * +/-INF == +/-INF
14946 * NAN != NAN
14948 * The vertex shader value is written to the red component, with 0.0
14949 * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
14950 * result in 0x00. The pixel shader value is written to the green
14951 * component, but here 0.0 also results in 0x00. The actual value is
14952 * written to the blue component.
14954 * There are considerable differences between graphics cards in how
14955 * these are handled, but pow and nrm never generate INF or NAN on
14956 * real hardware. */
14957 {"log", vs_log, sizeof(vs_log), 0x00000000, 0x00000000, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
14958 {"pow", vs_pow, sizeof(vs_pow), 0x000000ff, 0x000000ff, 0x0000ff00, 0x000000ff, 0x00008000},
14959 {"nrm", vs_nrm, sizeof(vs_nrm), 0x00ff0000, 0x00ff0000, 0x0000ff00, 0x00ff0000, 0x00008000},
14960 {"rcp1", vs_rcp1, sizeof(vs_rcp1), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
14961 {"rcp2", vs_rcp2, sizeof(vs_rcp2), 0x000000ff, 0x00000000, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
14962 {"rsq1", vs_rsq1, sizeof(vs_rsq1), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
14963 {"rsq2", vs_rsq2, sizeof(vs_rsq2), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
14964 {"lit", vs_lit, sizeof(vs_lit), 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
14965 {"def1", vs_def1, sizeof(vs_def1), 0x000000ff, 0x00007f00, 0x0000ff00, 0x00007f00, 0x00008000},
14966 {"def2", vs_def2, sizeof(vs_def2), 0x00ff0000, 0x00ff7f00, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
14967 {"def3", vs_def3, sizeof(vs_def3), 0x00ff00ff, 0x00ff7f00, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
14970 static const DWORD ps_code[] =
14972 0xffff0200, /* ps_2_0 */
14973 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
14974 0x0200001f, 0x80000000, 0xb0030000, /* dcl t0.xy */
14975 0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000, /* max r1.x, t0, c0 */
14976 0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000, /* min r0.x, t0, c0 */
14977 0x03000002, 0x80010000, 0x80e40000, 0x81e40001, /* add r0.x, r0, -r1 */
14978 0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000, /* mad r1.x, t0, c0.w. -t0 */
14979 0x02000023, 0x80010002, 0x80e40001, /* abs r2.x, r1 */
14980 0x02000023, 0x80010000, 0x80e40000, /* abs r0.x, r0 */
14981 0x02000023, 0x80010001, 0xb0e40000, /* abs r1.x, t0 */
14982 0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r2, c0.z, c0 */
14983 0x02000023, 0x80010002, 0x80e40002, /* abs r2.x, r2 */
14984 0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r1.x, -r1, c0.z, c0 */
14985 0x02000023, 0x80010001, 0x80e40001, /* abs r1.x, r1 */
14986 0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r3.x, -r2, c0.z, c0 */
14987 0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r1, c0.z, c0 */
14988 0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000, /* cmp r0.x, -r0, c0.y, c0 */
14989 0x03000005, 0x80010002, 0x80e40002, 0x80e40003, /* mul r2.x, r2, r3 */
14990 0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000, /* cmp r0.x, -r2, c0.z, r0 */
14991 0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000, /* cmp r0.y, -r1.x, r0.x, c0.x */
14992 0x02000001, 0x80050000, 0xb0c90000, /* mov r0.xz, t0.yzxw */
14993 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.w, c0.z */
14994 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14995 0x0000ffff, /* end */
14998 struct
15000 float x, y, z;
15001 float s;
15003 quad[] =
15005 { -1.0f, 1.0f, 0.0f, 0.0f},
15006 { 1.0f, 1.0f, 1.0f, 0.0f},
15007 { -1.0f, -1.0f, 0.0f, 0.0f},
15008 { 1.0f, -1.0f, 1.0f, 0.0f},
15011 IDirect3DPixelShader9 *ps;
15012 IDirect3DDevice9 *device;
15013 UINT body_size = 0;
15014 IDirect3D9 *d3d;
15015 DWORD *vs_code;
15016 ULONG refcount;
15017 D3DCAPS9 caps;
15018 HWND window;
15019 HRESULT hr;
15020 UINT i;
15022 window = create_window();
15023 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15024 ok(!!d3d, "Failed to create a D3D object.\n");
15025 if (!(device = create_device(d3d, window, window, TRUE)))
15027 skip("Failed to create a D3D device, skipping tests.\n");
15028 goto done;
15031 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15032 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
15033 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
15035 skip("No shader model 2.0 support, skipping floating point specials test.\n");
15036 IDirect3DDevice9_Release(device);
15037 goto done;
15040 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
15041 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15043 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
15044 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
15045 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15046 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
15048 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
15049 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15051 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
15052 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
15054 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
15056 if (vs_body[i].size > body_size) body_size = vs_body[i].size;
15059 vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
15060 memcpy(vs_code, vs_header, sizeof(vs_header));
15062 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
15064 DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
15065 IDirect3DVertexShader9 *vs;
15066 D3DCOLOR color;
15068 memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
15069 offset += vs_body[i].size / sizeof(*vs_body[i].ops);
15070 memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
15072 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
15073 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
15074 hr = IDirect3DDevice9_SetVertexShader(device, vs);
15075 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
15077 hr = IDirect3DDevice9_BeginScene(device);
15078 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15079 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15080 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15081 hr = IDirect3DDevice9_EndScene(device);
15082 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15084 color = getPixelColor(device, 320, 240);
15085 ok(color_match(color, vs_body[i].r500, 1)
15086 || color_match(color, vs_body[i].r600, 1)
15087 || color_match(color, vs_body[i].nv40, 1)
15088 || color_match(color, vs_body[i].nv50, 1)
15089 || broken(color_match(color, vs_body[i].warp, 1)),
15090 "Expected color 0x%08x, 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
15091 vs_body[i].r500, vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
15093 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15094 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
15096 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
15097 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
15098 IDirect3DVertexShader9_Release(vs);
15101 HeapFree(GetProcessHeap(), 0, vs_code);
15103 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
15104 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
15105 IDirect3DPixelShader9_Release(ps);
15106 refcount = IDirect3DDevice9_Release(device);
15107 ok(!refcount, "Device has %u references left.\n", refcount);
15108 done:
15109 IDirect3D9_Release(d3d);
15110 DestroyWindow(window);
15113 static void srgbwrite_format_test(void)
15115 IDirect3D9 *d3d;
15116 IDirect3DSurface9 *rt, *backbuffer;
15117 IDirect3DTexture9 *texture;
15118 IDirect3DDevice9 *device;
15119 ULONG refcount;
15120 HWND window;
15121 HRESULT hr;
15122 int i;
15123 DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
15124 static const struct
15126 D3DFORMAT fmt;
15127 const char *name;
15129 formats[] =
15131 { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
15132 { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
15133 { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
15134 { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
15135 { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
15137 static const struct
15139 float x, y, z;
15140 float u, v;
15142 quad[] =
15144 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
15145 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
15146 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
15147 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
15150 window = create_window();
15151 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15152 ok(!!d3d, "Failed to create a D3D object.\n");
15153 if (!(device = create_device(d3d, window, window, TRUE)))
15155 skip("Failed to create a D3D device, skipping tests.\n");
15156 goto done;
15159 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
15160 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15161 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
15162 ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
15163 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
15164 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
15165 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
15166 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15168 for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
15170 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
15171 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
15173 skip("Format %s not supported as render target, skipping test.\n",
15174 formats[i].name);
15175 continue;
15178 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET,
15179 formats[i].fmt, D3DPOOL_DEFAULT, &texture, NULL);
15180 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
15181 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
15182 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
15184 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
15185 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
15186 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15187 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
15188 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
15189 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
15191 hr = IDirect3DDevice9_BeginScene(device);
15192 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15194 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
15195 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
15196 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
15197 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
15198 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15199 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15201 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
15202 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
15203 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
15204 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15205 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
15206 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
15207 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
15208 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
15209 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15210 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15211 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15212 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
15214 hr = IDirect3DDevice9_EndScene(device);
15215 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15217 IDirect3DSurface9_Release(rt);
15218 IDirect3DTexture9_Release(texture);
15220 color = getPixelColor(device, 360, 240);
15221 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
15222 D3DUSAGE_QUERY_SRGBWRITE,
15223 D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
15225 /* Big slop for R5G6B5 */
15226 ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
15227 formats[i].name, color_srgb, color);
15229 else
15231 /* Big slop for R5G6B5 */
15232 ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
15233 formats[i].name, color_rgb, color);
15236 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15237 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
15240 IDirect3DSurface9_Release(backbuffer);
15241 refcount = IDirect3DDevice9_Release(device);
15242 ok(!refcount, "Device has %u references left.\n", refcount);
15243 done:
15244 IDirect3D9_Release(d3d);
15245 DestroyWindow(window);
15248 static void ds_size_test(void)
15250 IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
15251 IDirect3DDevice9 *device;
15252 DWORD num_passes;
15253 IDirect3D9 *d3d;
15254 ULONG refcount;
15255 HWND window;
15256 HRESULT hr;
15258 static const struct
15260 float x, y, z;
15262 quad[] =
15264 {-1.0f, -1.0f, 0.0f},
15265 {-1.0f, 1.0f, 0.0f},
15266 { 1.0f, -1.0f, 0.0f},
15267 { 1.0f, 1.0f, 0.0f},
15270 window = create_window();
15271 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15272 ok(!!d3d, "Failed to create a D3D object.\n");
15273 if (!(device = create_device(d3d, window, window, TRUE)))
15275 skip("Failed to create a D3D device, skipping tests.\n");
15276 goto done;
15279 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
15280 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
15281 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
15282 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#x.\n", hr);
15283 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
15284 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
15286 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
15287 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
15289 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
15290 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15291 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
15292 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15293 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
15294 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15295 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15296 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
15297 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
15298 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
15299 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
15300 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#x.\n", hr);
15301 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15302 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
15303 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15304 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
15305 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15306 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
15308 /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
15309 * but does not change the surface's contents. */
15310 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
15311 ok(SUCCEEDED(hr), "Target clear failed, hr %#x.\n", hr);
15312 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
15313 ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#x.\n", hr);
15314 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
15315 ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#x.\n", hr);
15317 /* Nvidia does not clear the surface(The color is still 0x000000ff), AMD does(the color is 0x00ff0000) */
15319 /* Turning on any depth-related state results in a ValidateDevice failure */
15320 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15321 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15322 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15323 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
15324 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
15325 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
15326 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15327 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15328 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15329 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15330 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
15331 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
15333 /* Try to draw with the device in an invalid state. */
15334 hr = IDirect3DDevice9_BeginScene(device);
15335 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15336 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15337 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15338 hr = IDirect3DDevice9_EndScene(device);
15339 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15341 /* Don't check the resulting draw unless we find an app that needs it. On
15342 * NVIDIA ValidateDevice() returns CONFLICTINGRENDERSTATE, so the result
15343 * is undefined. On AMD D3D seems to assume the stored Z buffer value is
15344 * 0.0 for all pixels, even those that are covered by the depth buffer. */
15346 hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
15347 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
15348 hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
15349 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
15350 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15351 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
15353 IDirect3DSurface9_Release(readback);
15354 IDirect3DSurface9_Release(ds);
15355 IDirect3DSurface9_Release(rt);
15356 IDirect3DSurface9_Release(old_rt);
15357 IDirect3DSurface9_Release(old_ds);
15358 refcount = IDirect3DDevice9_Release(device);
15359 ok(!refcount, "Device has %u references left.\n", refcount);
15360 done:
15361 IDirect3D9_Release(d3d);
15362 DestroyWindow(window);
15365 static void unbound_sampler_test(void)
15367 IDirect3DPixelShader9 *ps, *ps_cube, *ps_volume;
15368 IDirect3DSurface9 *rt, *old_rt;
15369 IDirect3DDevice9 *device;
15370 IDirect3D9 *d3d;
15371 ULONG refcount;
15372 D3DCAPS9 caps;
15373 DWORD color;
15374 HWND window;
15375 HRESULT hr;
15377 static const DWORD ps_code[] =
15379 0xffff0200, /* ps_2_0 */
15380 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
15381 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
15382 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
15383 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15384 0x0000ffff, /* end */
15386 static const DWORD ps_code_cube[] =
15388 0xffff0200, /* ps_2_0 */
15389 0x0200001f, 0x98000000, 0xa00f0800, /* dcl_cube s0 */
15390 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
15391 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
15392 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15393 0x0000ffff, /* end */
15395 static const DWORD ps_code_volume[] =
15397 0xffff0200, /* ps_2_0 */
15398 0x0200001f, 0xa0000000, 0xa00f0800, /* dcl_volume s0 */
15399 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
15400 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
15401 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15402 0x0000ffff, /* end */
15405 static const struct
15407 float x, y, z;
15408 float u, v;
15410 quad[] =
15412 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
15413 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
15414 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
15415 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
15418 window = create_window();
15419 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15420 ok(!!d3d, "Failed to create a D3D object.\n");
15421 if (!(device = create_device(d3d, window, window, TRUE)))
15423 skip("Failed to create a D3D device, skipping tests.\n");
15424 goto done;
15427 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15428 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
15429 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
15431 skip("No ps_2_0 support, skipping tests.\n");
15432 IDirect3DDevice9_Release(device);
15433 goto done;
15435 if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP) || !(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
15437 skip("No cube / volume texture support, skipping tests.\n");
15438 IDirect3DDevice9_Release(device);
15439 goto done;
15442 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15443 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStage failed, %#x.\n", hr);
15445 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
15446 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
15447 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_cube, &ps_cube);
15448 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
15449 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_volume, &ps_volume);
15450 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
15452 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
15453 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
15455 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
15456 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
15458 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15459 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
15461 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 );
15462 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
15464 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x56ffffff, 1.0f, 0);
15465 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
15467 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15468 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
15470 hr = IDirect3DDevice9_BeginScene(device);
15471 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15472 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15473 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15474 hr = IDirect3DDevice9_EndScene(device);
15475 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15477 color = getPixelColorFromSurface(rt, 32, 32);
15478 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
15480 /* Now try with a cube texture */
15481 hr = IDirect3DDevice9_SetPixelShader(device, ps_cube);
15482 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
15484 hr = IDirect3DDevice9_BeginScene(device);
15485 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15486 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15487 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15488 hr = IDirect3DDevice9_EndScene(device);
15489 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15491 color = getPixelColorFromSurface(rt, 32, 32);
15492 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
15494 /* And then with a volume texture */
15495 hr = IDirect3DDevice9_SetPixelShader(device, ps_volume);
15496 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
15498 hr = IDirect3DDevice9_BeginScene(device);
15499 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15500 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15501 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15502 hr = IDirect3DDevice9_EndScene(device);
15503 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15505 color = getPixelColorFromSurface(rt, 32, 32);
15506 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
15508 IDirect3DSurface9_Release(rt);
15509 IDirect3DSurface9_Release(old_rt);
15510 IDirect3DPixelShader9_Release(ps);
15511 IDirect3DPixelShader9_Release(ps_cube);
15512 IDirect3DPixelShader9_Release(ps_volume);
15513 refcount = IDirect3DDevice9_Release(device);
15514 ok(!refcount, "Device has %u references left.\n", refcount);
15515 done:
15516 IDirect3D9_Release(d3d);
15517 DestroyWindow(window);
15520 static void update_surface_test(void)
15522 static const BYTE blocks[][8] =
15524 {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, /* White */
15525 {0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Red */
15526 {0xe0, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00}, /* Yellow */
15527 {0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Green */
15528 {0xff, 0x07, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Cyan */
15529 {0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Blue */
15530 {0x1f, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Magenta */
15532 static const struct
15534 UINT x, y;
15535 D3DCOLOR color;
15537 expected_colors[] =
15539 { 18, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0xff)},
15540 { 57, 240, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff)},
15541 {109, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0xff)},
15542 {184, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
15543 {290, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
15544 {440, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
15545 {584, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
15547 static const struct
15549 float x, y, z, w;
15550 float u, v;
15552 tri[] =
15554 { 0.0f, 480.0f, 0.0f, 1.0f, 0.0f, 0.0f},
15555 { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
15556 {640.0f, 240.0f, 0.0f, 10.0f, 100.0f, 0.5f},
15558 static const RECT rect_2x2 = {0, 0, 2, 2};
15559 static const struct
15561 UINT src_level;
15562 UINT dst_level;
15563 const RECT *r;
15564 HRESULT hr;
15566 block_size_tests[] =
15568 {1, 0, NULL, D3D_OK},
15569 {0, 1, NULL, D3DERR_INVALIDCALL},
15570 {5, 4, NULL, D3DERR_INVALIDCALL},
15571 {4, 5, NULL, D3DERR_INVALIDCALL},
15572 {4, 5, &rect_2x2, D3DERR_INVALIDCALL},
15573 {5, 5, &rect_2x2, D3D_OK},
15576 IDirect3DSurface9 *src_surface, *dst_surface;
15577 IDirect3DTexture9 *src_tex, *dst_tex;
15578 IDirect3DDevice9 *device;
15579 IDirect3D9 *d3d;
15580 ULONG refcount;
15581 UINT count, i;
15582 HWND window;
15583 HRESULT hr;
15585 window = create_window();
15586 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15587 ok(!!d3d, "Failed to create a D3D object.\n");
15588 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15589 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1)))
15591 skip("DXT1 not supported, skipping tests.\n");
15592 goto done;
15594 if (!(device = create_device(d3d, window, window, TRUE)))
15596 skip("Failed to create a D3D device, skipping tests.\n");
15597 goto done;
15600 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &src_tex, NULL);
15601 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
15602 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &dst_tex, NULL);
15603 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
15605 count = IDirect3DTexture9_GetLevelCount(src_tex);
15606 ok(count == 7, "Got level count %u, expected 7.\n", count);
15608 for (i = 0; i < count; ++i)
15610 UINT row_count, block_count, x, y;
15611 D3DSURFACE_DESC desc;
15612 BYTE *row, *block;
15613 D3DLOCKED_RECT r;
15615 hr = IDirect3DTexture9_GetLevelDesc(src_tex, i, &desc);
15616 ok(SUCCEEDED(hr), "Failed to get level desc, hr %#x.\n", hr);
15618 hr = IDirect3DTexture9_LockRect(src_tex, i, &r, NULL, 0);
15619 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
15621 row_count = ((desc.Height + 3) & ~3) / 4;
15622 block_count = ((desc.Width + 3) & ~3) / 4;
15623 row = r.pBits;
15625 for (y = 0; y < row_count; ++y)
15627 block = row;
15628 for (x = 0; x < block_count; ++x)
15630 memcpy(block, blocks[i], sizeof(blocks[i]));
15631 block += sizeof(blocks[i]);
15633 row += r.Pitch;
15636 hr = IDirect3DTexture9_UnlockRect(src_tex, i);
15637 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
15640 for (i = 0; i < sizeof(block_size_tests) / sizeof(*block_size_tests); ++i)
15642 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, block_size_tests[i].src_level, &src_surface);
15643 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15644 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, block_size_tests[i].dst_level, &dst_surface);
15645 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15647 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, block_size_tests[i].r, dst_surface, NULL);
15648 ok(hr == block_size_tests[i].hr, "Update surface returned %#x for test %u, expected %#x.\n",
15649 hr, i, block_size_tests[i].hr);
15651 IDirect3DSurface9_Release(dst_surface);
15652 IDirect3DSurface9_Release(src_surface);
15655 for (i = 0; i < count; ++i)
15657 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, i, &src_surface);
15658 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15659 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, i, &dst_surface);
15660 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15662 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, NULL, dst_surface, NULL);
15663 ok(SUCCEEDED(hr), "Failed to update surface at level %u, hr %#x.\n", i, hr);
15665 IDirect3DSurface9_Release(dst_surface);
15666 IDirect3DSurface9_Release(src_surface);
15669 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15670 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15671 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
15672 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15673 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
15674 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15675 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)dst_tex);
15676 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
15677 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
15678 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
15679 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
15680 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
15682 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
15683 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
15685 hr = IDirect3DDevice9_BeginScene(device);
15686 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15687 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 1, tri, sizeof(*tri));
15688 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15689 hr = IDirect3DDevice9_EndScene(device);
15690 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15692 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15694 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
15695 ok(color_match(color, expected_colors[i].color, 0),
15696 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15697 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15700 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15701 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
15703 IDirect3DTexture9_Release(dst_tex);
15704 IDirect3DTexture9_Release(src_tex);
15705 refcount = IDirect3DDevice9_Release(device);
15706 ok(!refcount, "Device has %u references left.\n", refcount);
15707 done:
15708 IDirect3D9_Release(d3d);
15709 DestroyWindow(window);
15712 static void multisample_get_rtdata_test(void)
15714 IDirect3DSurface9 *original_ds, *original_rt, *rt, *readback;
15715 IDirect3DDevice9 *device;
15716 IDirect3D9 *d3d;
15717 ULONG refcount;
15718 HWND window;
15719 HRESULT hr;
15721 window = create_window();
15722 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15723 ok(!!d3d, "Failed to create a D3D object.\n");
15724 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15725 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15727 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping tests.\n");
15728 goto done;
15730 if (!(device = create_device(d3d, window, window, TRUE)))
15732 skip("Failed to create a D3D device, skipping tests.\n");
15733 goto done;
15736 hr = IDirect3DDevice9_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
15737 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
15738 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
15739 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_A8R8G8B8,
15740 D3DPOOL_SYSTEMMEM, &readback, NULL);
15741 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
15743 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
15744 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
15745 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
15746 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
15748 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15749 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15750 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15751 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15753 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
15754 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15755 hr = IDirect3DDevice9_GetRenderTargetData(device, rt, readback);
15756 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
15758 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
15759 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15760 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15761 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
15763 IDirect3DSurface9_Release(original_ds);
15764 IDirect3DSurface9_Release(original_rt);
15765 IDirect3DSurface9_Release(readback);
15766 IDirect3DSurface9_Release(rt);
15767 refcount = IDirect3DDevice9_Release(device);
15768 ok(!refcount, "Device has %u references left.\n", refcount);
15769 done:
15770 IDirect3D9_Release(d3d);
15771 DestroyWindow(window);
15774 static void multisampled_depth_buffer_test(void)
15776 IDirect3DDevice9 *device = 0;
15777 IDirect3DSurface9 *original_rt, *rt, *readback, *ds, *original_ds;
15778 IDirect3D9 *d3d;
15779 D3DCAPS9 caps;
15780 HRESULT hr;
15781 D3DPRESENT_PARAMETERS present_parameters;
15782 unsigned int i;
15783 static const struct
15785 float x, y, z;
15786 D3DCOLOR color;
15788 quad_1[] =
15790 { -1.0f, 1.0f, 0.0f, 0xffff0000},
15791 { 1.0f, 1.0f, 1.0f, 0xffff0000},
15792 { -1.0f, -1.0f, 0.0f, 0xffff0000},
15793 { 1.0f, -1.0f, 1.0f, 0xffff0000},
15795 quad_2[] =
15797 { -1.0f, 1.0f, 1.0f, 0xff0000ff},
15798 { 1.0f, 1.0f, 0.0f, 0xff0000ff},
15799 { -1.0f, -1.0f, 1.0f, 0xff0000ff},
15800 { 1.0f, -1.0f, 0.0f, 0xff0000ff},
15802 static const struct
15804 UINT x, y;
15805 D3DCOLOR color;
15807 expected_colors[] =
15809 { 80, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15810 {240, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15811 {400, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15812 {560, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15813 { 80, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15814 {240, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15815 {400, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15816 {560, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15819 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15820 ok(!!d3d, "Failed to create a D3D object.\n");
15822 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
15823 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15825 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled depth buffer test.\n");
15826 IDirect3D9_Release(d3d);
15827 return;
15829 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
15830 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15832 skip("Multisampling not supported for D3DFMT_D24S8, skipping multisampled depth buffer test.\n");
15833 IDirect3D9_Release(d3d);
15834 return;
15837 ZeroMemory(&present_parameters, sizeof(present_parameters));
15838 present_parameters.Windowed = TRUE;
15839 present_parameters.hDeviceWindow = create_window();
15840 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
15841 present_parameters.BackBufferWidth = 640;
15842 present_parameters.BackBufferHeight = 480;
15843 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
15844 present_parameters.EnableAutoDepthStencil = TRUE;
15845 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
15846 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
15848 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15849 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
15850 &present_parameters, &device);
15851 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
15853 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15854 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
15855 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
15857 skip("No unconditional NP2 texture support, skipping multisampled depth buffer test.\n");
15858 goto cleanup;
15861 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15862 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
15863 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
15864 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15865 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
15866 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
15868 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
15869 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
15870 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
15871 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
15873 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15874 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15875 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15876 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15877 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15878 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15879 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
15880 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15881 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
15882 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15884 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
15885 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15887 /* Render onscreen and then offscreen */
15888 hr = IDirect3DDevice9_BeginScene(device);
15889 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15890 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
15891 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15892 hr = IDirect3DDevice9_EndScene(device);
15893 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15895 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, rt, NULL, D3DTEXF_POINT);
15896 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15897 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15898 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15900 hr = IDirect3DDevice9_BeginScene(device);
15901 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15902 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
15903 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15904 hr = IDirect3DDevice9_EndScene(device);
15905 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15907 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, readback, NULL, D3DTEXF_POINT);
15908 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15910 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15912 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
15913 ok(color_match(color, expected_colors[i].color, 1),
15914 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15915 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15918 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
15919 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15920 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15921 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
15923 /* Render offscreen and then onscreen */
15924 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15925 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15926 IDirect3DSurface9_Release(ds);
15927 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
15928 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
15929 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#x.\n", hr);
15930 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15931 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15933 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
15934 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15936 hr = IDirect3DDevice9_BeginScene(device);
15937 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15938 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
15939 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15940 hr = IDirect3DDevice9_EndScene(device);
15941 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15943 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
15944 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15945 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15946 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15948 hr = IDirect3DDevice9_BeginScene(device);
15949 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15950 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
15951 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15952 hr = IDirect3DDevice9_EndScene(device);
15953 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15955 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
15956 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15958 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15960 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
15961 ok(color_match(color, expected_colors[i].color, 1),
15962 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15963 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15966 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15967 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
15969 IDirect3DSurface9_Release(ds);
15970 IDirect3DSurface9_Release(readback);
15971 IDirect3DSurface9_Release(rt);
15972 IDirect3DSurface9_Release(original_rt);
15973 cleanup_device(device);
15975 ZeroMemory(&present_parameters, sizeof(present_parameters));
15976 present_parameters.Windowed = TRUE;
15977 present_parameters.hDeviceWindow = create_window();
15978 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
15979 present_parameters.BackBufferWidth = 640;
15980 present_parameters.BackBufferHeight = 480;
15981 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
15982 present_parameters.EnableAutoDepthStencil = TRUE;
15983 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
15984 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
15986 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15987 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
15988 &present_parameters, &device);
15989 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
15991 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
15992 ok(SUCCEEDED(hr), "Failed to clear depth buffer, hr %#x.\n", hr);
15994 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15995 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
15996 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
15997 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15998 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
15999 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
16000 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
16001 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
16002 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
16004 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
16005 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
16006 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
16007 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
16008 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
16009 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16010 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16011 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16013 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16014 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16015 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
16016 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16017 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16018 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16019 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
16020 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16021 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
16022 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
16024 /* Render to a multisampled offscreen frame buffer and then blit to
16025 * the onscreen (not multisampled) frame buffer. */
16026 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
16027 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16029 hr = IDirect3DDevice9_BeginScene(device);
16030 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16031 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
16032 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16033 hr = IDirect3DDevice9_EndScene(device);
16034 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16036 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
16037 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
16038 hr = IDirect3DDevice9_StretchRect(device, ds, NULL, original_ds, NULL, D3DTEXF_POINT);
16039 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
16041 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16042 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16043 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
16044 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16046 hr = IDirect3DDevice9_BeginScene(device);
16047 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16048 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
16049 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16050 hr = IDirect3DDevice9_EndScene(device);
16051 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16053 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
16054 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
16056 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16058 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
16059 ok(color_match(color, expected_colors[i].color, 1),
16060 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16061 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16064 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16065 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16067 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16068 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16069 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16070 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
16072 IDirect3DSurface9_Release(original_ds);
16073 IDirect3DSurface9_Release(original_rt);
16074 IDirect3DSurface9_Release(ds);
16075 IDirect3DSurface9_Release(readback);
16076 IDirect3DSurface9_Release(rt);
16077 cleanup:
16078 cleanup_device(device);
16079 IDirect3D9_Release(d3d);
16082 static void resz_test(void)
16084 IDirect3DDevice9 *device = 0;
16085 IDirect3DSurface9 *rt, *original_rt, *ds, *readback, *intz_ds;
16086 D3DCAPS9 caps;
16087 HRESULT hr;
16088 D3DPRESENT_PARAMETERS present_parameters;
16089 unsigned int i;
16090 static const DWORD ps_code[] =
16092 0xffff0200, /* ps_2_0 */
16093 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
16094 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
16095 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
16096 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
16097 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
16098 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
16099 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
16100 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
16101 0x02000001, 0x800f0800, 0x80e40001, /* mov oC0, r1 */
16102 0x0000ffff, /* end */
16104 static const struct
16106 float x, y, z;
16107 float s, t, p, q;
16109 quad[] =
16111 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
16112 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
16113 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
16114 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
16116 static const struct
16118 UINT x, y;
16119 D3DCOLOR color;
16121 expected_colors[] =
16123 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
16124 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
16125 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
16126 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
16127 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
16128 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
16129 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
16130 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
16132 IDirect3DTexture9 *texture;
16133 IDirect3DPixelShader9 *ps;
16134 IDirect3D9 *d3d;
16135 DWORD value;
16137 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16138 ok(!!d3d, "Failed to create a D3D object.\n");
16140 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
16141 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
16143 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
16144 IDirect3D9_Release(d3d);
16145 return;
16147 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
16148 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
16150 skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
16151 IDirect3D9_Release(d3d);
16152 return;
16155 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
16156 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
16158 skip("No INTZ support, skipping RESZ test.\n");
16159 IDirect3D9_Release(d3d);
16160 return;
16163 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
16164 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'))))
16166 skip("No RESZ support, skipping RESZ test.\n");
16167 IDirect3D9_Release(d3d);
16168 return;
16171 ZeroMemory(&present_parameters, sizeof(present_parameters));
16172 present_parameters.Windowed = TRUE;
16173 present_parameters.hDeviceWindow = create_window();
16174 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
16175 present_parameters.BackBufferWidth = 640;
16176 present_parameters.BackBufferHeight = 480;
16177 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
16178 present_parameters.EnableAutoDepthStencil = FALSE;
16179 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
16180 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
16182 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16183 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
16184 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
16186 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16187 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
16188 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
16190 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
16191 cleanup_device(device);
16192 IDirect3D9_Release(d3d);
16193 return;
16195 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
16197 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
16198 cleanup_device(device);
16199 IDirect3D9_Release(d3d);
16200 return;
16203 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
16204 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
16206 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
16207 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
16208 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
16209 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
16210 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
16211 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#x.\n", hr);
16212 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
16213 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
16214 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
16216 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
16217 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
16218 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
16219 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
16220 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
16221 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
16222 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16223 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
16224 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
16225 IDirect3DSurface9_Release(intz_ds);
16226 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
16227 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
16229 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
16230 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
16231 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
16232 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16233 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
16234 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16235 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16236 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16237 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16238 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16240 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
16241 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16242 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
16243 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16244 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
16245 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16246 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
16247 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16248 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
16249 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16251 /* Render offscreen (multisampled), blit the depth buffer
16252 * into the INTZ texture and then check its contents */
16253 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
16254 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16255 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16256 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16257 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
16258 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16260 hr = IDirect3DDevice9_BeginScene(device);
16261 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16262 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16263 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16265 /* The destination depth texture has to be bound to sampler 0 */
16266 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16267 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16269 /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
16270 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
16271 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16272 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
16273 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16274 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
16275 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16276 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16277 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16278 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
16279 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16280 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16281 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16282 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
16283 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16285 /* The actual multisampled depth buffer resolve happens here */
16286 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16287 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16288 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
16289 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
16291 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16292 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16293 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16294 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16295 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16296 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16298 /* Read the depth values back */
16299 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16300 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16301 hr = IDirect3DDevice9_EndScene(device);
16302 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16304 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16306 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
16307 ok(color_match(color, expected_colors[i].color, 1),
16308 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16309 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16312 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16313 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16315 IDirect3DSurface9_Release(ds);
16316 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16317 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16318 IDirect3DTexture9_Release(texture);
16319 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16320 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16321 IDirect3DPixelShader9_Release(ps);
16322 IDirect3DSurface9_Release(readback);
16323 IDirect3DSurface9_Release(original_rt);
16324 IDirect3DSurface9_Release(rt);
16325 cleanup_device(device);
16327 ZeroMemory(&present_parameters, sizeof(present_parameters));
16328 present_parameters.Windowed = TRUE;
16329 present_parameters.hDeviceWindow = create_window();
16330 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
16331 present_parameters.BackBufferWidth = 640;
16332 present_parameters.BackBufferHeight = 480;
16333 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
16334 present_parameters.EnableAutoDepthStencil = TRUE;
16335 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
16336 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
16338 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16339 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
16340 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
16342 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
16343 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
16344 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
16345 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
16346 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
16347 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
16348 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
16349 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
16350 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
16351 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
16352 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
16353 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
16354 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
16355 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16356 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
16357 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16358 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
16359 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
16360 IDirect3DSurface9_Release(intz_ds);
16361 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
16362 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
16364 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
16365 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
16366 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
16367 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16368 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
16369 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16370 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16371 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16372 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16373 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16375 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
16376 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16377 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
16378 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16379 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
16380 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16381 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
16382 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16383 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
16384 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16386 /* Render onscreen, blit the depth buffer into the INTZ texture
16387 * and then check its contents */
16388 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16389 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16390 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16391 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16392 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
16393 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16395 hr = IDirect3DDevice9_BeginScene(device);
16396 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16397 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16398 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16399 hr = IDirect3DDevice9_EndScene(device);
16400 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16402 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16403 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16405 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
16406 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16407 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
16408 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16409 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
16410 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16411 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16412 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16413 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
16414 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16415 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16416 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16417 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
16418 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16420 /* The actual multisampled depth buffer resolve happens here */
16421 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16422 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16423 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
16424 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
16426 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
16427 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16428 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16429 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16430 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16431 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16433 /* Read the depth values back */
16434 hr = IDirect3DDevice9_BeginScene(device);
16435 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16436 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16437 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16438 hr = IDirect3DDevice9_EndScene(device);
16439 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16441 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16443 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
16444 ok(color_match(color, expected_colors[i].color, 1),
16445 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16446 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16449 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16450 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16453 /* Test edge cases - try with no texture at all */
16454 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16455 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16456 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16457 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16458 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16459 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16460 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16461 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16463 hr = IDirect3DDevice9_BeginScene(device);
16464 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16465 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16466 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16467 hr = IDirect3DDevice9_EndScene(device);
16468 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16470 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16471 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16473 /* With a non-multisampled depth buffer */
16474 IDirect3DSurface9_Release(ds);
16475 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
16476 D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
16477 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
16479 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
16480 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16481 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16482 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16483 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16484 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16486 hr = IDirect3DDevice9_BeginScene(device);
16487 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16488 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16489 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16491 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16492 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16494 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
16495 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16496 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
16497 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16498 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
16499 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16500 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16501 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16502 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
16503 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16504 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16505 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16506 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
16507 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16508 hr = IDirect3DDevice9_EndScene(device);
16509 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16511 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16512 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16514 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16515 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16517 /* Read the depth values back. */
16518 hr = IDirect3DDevice9_BeginScene(device);
16519 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16520 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16521 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16522 hr = IDirect3DDevice9_EndScene(device);
16523 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16525 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16527 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
16528 ok(color_match(color, expected_colors[i].color, 1),
16529 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16530 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16533 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16534 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16536 /* Without a current depth-stencil buffer set */
16537 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16538 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16539 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16540 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16542 hr = IDirect3DDevice9_BeginScene(device);
16543 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16544 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16545 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16546 hr = IDirect3DDevice9_EndScene(device);
16547 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16549 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16550 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16552 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16553 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16554 IDirect3DSurface9_Release(ds);
16555 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16556 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16557 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16558 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16559 IDirect3DTexture9_Release(texture);
16560 IDirect3DPixelShader9_Release(ps);
16561 IDirect3DSurface9_Release(readback);
16562 IDirect3DSurface9_Release(original_rt);
16563 cleanup_device(device);
16564 IDirect3D9_Release(d3d);
16567 static void zenable_test(void)
16569 static const struct
16571 struct vec4 position;
16572 D3DCOLOR diffuse;
16574 tquad[] =
16576 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
16577 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xff00ff00},
16578 {{640.0f, 480.0f, 1.5f, 1.0f}, 0xff00ff00},
16579 {{640.0f, 0.0f, 1.5f, 1.0f}, 0xff00ff00},
16581 IDirect3DDevice9 *device;
16582 IDirect3D9 *d3d;
16583 D3DCOLOR color;
16584 ULONG refcount;
16585 D3DCAPS9 caps;
16586 HWND window;
16587 HRESULT hr;
16588 UINT x, y;
16589 UINT i, j;
16590 UINT test;
16591 IDirect3DSurface9 *ds;
16593 window = create_window();
16594 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16595 ok(!!d3d, "Failed to create a D3D object.\n");
16596 if (!(device = create_device(d3d, window, window, TRUE)))
16598 skip("Failed to create a D3D device, skipping tests.\n");
16599 goto done;
16602 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
16603 ok(SUCCEEDED(hr), "Failed to get depth stencil surface, hr %#x.\n", hr);
16605 for (test = 0; test < 2; ++test)
16607 /* The Windows 8 testbot (WARP) appears to clip with
16608 * ZENABLE = D3DZB_TRUE and no depth buffer set. */
16609 static const D3DCOLOR expected_broken[] =
16611 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16612 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16613 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16614 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16617 if (!test)
16619 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16620 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
16622 else
16624 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
16625 ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
16626 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16627 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
16628 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.0f, 0);
16629 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16631 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
16632 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16634 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
16635 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16636 hr = IDirect3DDevice9_BeginScene(device);
16637 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16638 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
16639 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16640 hr = IDirect3DDevice9_EndScene(device);
16641 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16643 for (i = 0; i < 4; ++i)
16645 for (j = 0; j < 4; ++j)
16647 x = 80 * ((2 * j) + 1);
16648 y = 60 * ((2 * i) + 1);
16649 color = getPixelColor(device, x, y);
16650 ok(color_match(color, 0x0000ff00, 1)
16651 || broken(color_match(color, expected_broken[i * 4 + j], 1) && !test),
16652 "Expected color 0x0000ff00 at %u, %u, got 0x%08x, test %u.\n",
16653 x, y, color, test);
16657 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16658 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
16661 IDirect3DSurface9_Release(ds);
16663 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16664 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
16666 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
16667 && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
16669 static const DWORD vs_code[] =
16671 0xfffe0101, /* vs_1_1 */
16672 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
16673 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
16674 0x00000001, 0xd00f0000, 0x90e40000, /* mov oD0, v0 */
16675 0x0000ffff
16677 static const DWORD ps_code[] =
16679 0xffff0101, /* ps_1_1 */
16680 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
16681 0x0000ffff /* end */
16683 static const struct vec3 quad[] =
16685 {-1.0f, -1.0f, -0.5f},
16686 {-1.0f, 1.0f, -0.5f},
16687 { 1.0f, -1.0f, 1.5f},
16688 { 1.0f, 1.0f, 1.5f},
16690 static const D3DCOLOR expected[] =
16692 0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
16693 0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
16694 0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
16695 0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
16697 /* The Windows 8 testbot (WARP) appears to not clip z for regular
16698 * vertices either. */
16699 static const D3DCOLOR expected_broken[] =
16701 0x0020df20, 0x0060df60, 0x009fdf9f, 0x00dfdfdf,
16702 0x00209f20, 0x00609f60, 0x009f9f9f, 0x00df9fdf,
16703 0x00206020, 0x00606060, 0x009f609f, 0x00df60df,
16704 0x00202020, 0x00602060, 0x009f209f, 0x00df20df,
16707 IDirect3DVertexShader9 *vs;
16708 IDirect3DPixelShader9 *ps;
16710 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
16711 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16712 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
16713 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
16714 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
16715 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
16716 hr = IDirect3DDevice9_SetVertexShader(device, vs);
16717 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
16718 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16719 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
16721 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
16722 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16723 hr = IDirect3DDevice9_BeginScene(device);
16724 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16725 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16726 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16727 hr = IDirect3DDevice9_EndScene(device);
16728 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16730 for (i = 0; i < 4; ++i)
16732 for (j = 0; j < 4; ++j)
16734 x = 80 * ((2 * j) + 1);
16735 y = 60 * ((2 * i) + 1);
16736 color = getPixelColor(device, x, y);
16737 ok(color_match(color, expected[i * 4 + j], 1)
16738 || broken(color_match(color, expected_broken[i * 4 + j], 1)),
16739 "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
16743 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16744 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
16746 IDirect3DPixelShader9_Release(ps);
16747 IDirect3DVertexShader9_Release(vs);
16750 refcount = IDirect3DDevice9_Release(device);
16751 ok(!refcount, "Device has %u references left.\n", refcount);
16752 done:
16753 IDirect3D9_Release(d3d);
16754 DestroyWindow(window);
16757 static void fog_special_test(void)
16759 static const struct
16761 struct vec3 position;
16762 D3DCOLOR diffuse;
16764 quad[] =
16766 {{ -1.0f, -1.0f, 0.0f}, 0xff00ff00},
16767 {{ -1.0f, 1.0f, 0.0f}, 0xff00ff00},
16768 {{ 1.0f, -1.0f, 1.0f}, 0xff00ff00},
16769 {{ 1.0f, 1.0f, 1.0f}, 0xff00ff00}
16771 static const struct
16773 DWORD vertexmode, tablemode;
16774 BOOL vs, ps;
16775 D3DCOLOR color_left, color_right;
16777 tests[] =
16779 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, FALSE, 0x00ff0000, 0x00ff0000},
16780 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, TRUE, 0x00ff0000, 0x00ff0000},
16781 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, FALSE, 0x00ff0000, 0x00ff0000},
16782 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, TRUE, 0x00ff0000, 0x00ff0000},
16784 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, FALSE, 0x0000ff00, 0x00ff0000},
16785 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, TRUE, 0x0000ff00, 0x00ff0000},
16786 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, FALSE, 0x0000ff00, 0x00ff0000},
16787 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, TRUE, 0x0000ff00, 0x00ff0000},
16789 static const DWORD pixel_shader_code[] =
16791 0xffff0101, /* ps_1_1 */
16792 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
16793 0x0000ffff
16795 static const DWORD vertex_shader_code[] =
16797 0xfffe0101, /* vs_1_1 */
16798 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
16799 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
16800 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
16801 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
16802 0x0000ffff
16804 static const D3DMATRIX identity =
16806 1.0f, 0.0f, 0.0f, 0.0f,
16807 0.0f, 1.0f, 0.0f, 0.0f,
16808 0.0f, 0.0f, 1.0f, 0.0f,
16809 0.0f, 0.0f, 0.0f, 1.0f,
16810 }}};
16811 union
16813 float f;
16814 DWORD d;
16815 } conv;
16816 DWORD color;
16817 HRESULT hr;
16818 unsigned int i;
16819 IDirect3DPixelShader9 *ps;
16820 IDirect3DVertexShader9 *vs;
16821 IDirect3DDevice9 *device;
16822 IDirect3D9 *d3d;
16823 ULONG refcount;
16824 D3DCAPS9 caps;
16825 HWND window;
16827 window = create_window();
16828 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16829 ok(!!d3d, "Failed to create a D3D object.\n");
16830 if (!(device = create_device(d3d, window, window, TRUE)))
16832 skip("Failed to create a D3D device, skipping tests.\n");
16833 goto done;
16836 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16837 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
16838 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
16840 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code, &vs);
16841 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
16843 else
16845 skip("Vertex Shaders not supported, skipping some fog tests.\n");
16846 vs = NULL;
16848 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
16850 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &ps);
16851 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
16853 else
16855 skip("Pixel Shaders not supported, skipping some fog tests.\n");
16856 ps = NULL;
16859 /* The table fog tests seem to depend on the projection matrix explicitly
16860 * being set to an identity matrix, even though that's the default.
16861 * (AMD Radeon HD 6310, Windows 7) */
16862 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
16863 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
16865 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
16866 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16867 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16868 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
16869 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
16870 ok(SUCCEEDED(hr), "Failed to enable fog, hr %#x.\n", hr);
16871 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffff0000);
16872 ok(SUCCEEDED(hr), "Failed to set fog color, hr %#x.\n", hr);
16874 conv.f = 0.5f;
16875 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, conv.d);
16876 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#x.\n", hr);
16877 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, conv.d);
16878 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#x.\n", hr);
16880 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
16882 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
16883 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16885 if (!tests[i].vs)
16887 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
16888 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
16890 else if (vs)
16892 hr = IDirect3DDevice9_SetVertexShader(device, vs);
16893 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
16895 else
16897 continue;
16900 if (!tests[i].ps)
16902 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16903 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
16905 else if (ps)
16907 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16908 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
16910 else
16912 continue;
16915 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vertexmode);
16916 ok(SUCCEEDED(hr), "Failed to set fogvertexmode, hr %#x.\n", hr);
16917 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tablemode);
16918 ok(SUCCEEDED(hr), "Failed to set fogtablemode, hr %#x.\n", hr);
16920 hr = IDirect3DDevice9_BeginScene(device);
16921 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16922 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16923 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16924 hr = IDirect3DDevice9_EndScene(device);
16925 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16927 color = getPixelColor(device, 310, 240);
16928 ok(color_match(color, tests[i].color_left, 1),
16929 "Expected left color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_left, color, i);
16930 color = getPixelColor(device, 330, 240);
16931 ok(color_match(color, tests[i].color_right, 1),
16932 "Expected right color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_right, color, i);
16934 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16935 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
16938 if (vs)
16939 IDirect3DVertexShader9_Release(vs);
16940 if (ps)
16941 IDirect3DPixelShader9_Release(ps);
16942 refcount = IDirect3DDevice9_Release(device);
16943 ok(!refcount, "Device has %u references left.\n", refcount);
16944 done:
16945 IDirect3D9_Release(d3d);
16946 DestroyWindow(window);
16949 static void volume_srgb_test(void)
16951 HRESULT hr;
16952 unsigned int i, j;
16953 IDirect3DVolumeTexture9 *tex1, *tex2;
16954 D3DPOOL pool;
16955 D3DLOCKED_BOX locked_box;
16956 IDirect3DDevice9 *device;
16957 IDirect3D9 *d3d;
16958 D3DCOLOR color;
16959 ULONG refcount;
16960 HWND window;
16962 static const struct
16964 BOOL srgb;
16965 DWORD color;
16967 tests[] =
16969 /* Try toggling on and off */
16970 { FALSE, 0x007f7f7f },
16971 { TRUE, 0x00363636 },
16972 { FALSE, 0x007f7f7f },
16974 static const struct
16976 struct vec3 pos;
16977 struct vec3 texcrd;
16979 quad[] =
16981 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
16982 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
16983 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
16984 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
16987 window = create_window();
16988 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16989 ok(!!d3d, "Failed to create a D3D object.\n");
16990 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
16991 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_VOLUMETEXTURE, D3DFMT_A8R8G8B8) != D3D_OK)
16993 skip("D3DFMT_A8R8G8B8 volume textures with SRGBREAD not supported.\n");
16994 goto done;
16996 if (!(device = create_device(d3d, window, window, TRUE)))
16998 skip("Failed to create a D3D device, skipping tests.\n");
16999 goto done;
17002 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17003 ok(SUCCEEDED(hr), "Failed to set color op 0, hr %#x.\n", hr);
17004 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
17005 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17006 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
17007 ok(SUCCEEDED(hr), "Failed to set color op 0, hr %#x.\n", hr);
17008 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
17009 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
17011 for (i = 0; i < 2; i++)
17013 if (!i)
17014 pool = D3DPOOL_SYSTEMMEM;
17015 else
17016 pool = D3DPOOL_MANAGED;
17018 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, 0, D3DFMT_A8R8G8B8, pool, &tex1, NULL);
17019 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
17020 hr = IDirect3DVolumeTexture9_LockBox(tex1, 0, &locked_box, NULL, 0);
17021 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
17022 *((DWORD *)locked_box.pBits) = 0x7f7f7f7f;
17023 hr = IDirect3DVolumeTexture9_UnlockBox(tex1, 0);
17024 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
17026 if (!i)
17028 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, 0,
17029 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
17030 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
17031 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex1, (IDirect3DBaseTexture9 *)tex2);
17032 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17033 IDirect3DVolumeTexture9_Release(tex1);
17035 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex2);
17036 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17037 IDirect3DVolumeTexture9_Release(tex2);
17039 else
17041 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex1);
17042 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17043 IDirect3DVolumeTexture9_Release(tex1);
17046 for (j = 0; j < sizeof(tests) / sizeof(*tests); j++)
17048 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, tests[j].srgb);
17049 ok(SUCCEEDED(hr), "Failed to set srgb state, hr %#x.\n", hr);
17051 hr = IDirect3DDevice9_BeginScene(device);
17052 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17053 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17054 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17055 hr = IDirect3DDevice9_EndScene(device);
17056 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17058 color = getPixelColor(device, 320, 240);
17059 ok(color_match(color, tests[j].color, 2),
17060 "Expected color 0x%08x, got 0x%08x, i = %u, j = %u.\n", tests[j].color, color, i, j);
17062 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17063 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
17067 refcount = IDirect3DDevice9_Release(device);
17068 ok(!refcount, "Device has %u references left.\n", refcount);
17069 done:
17070 IDirect3D9_Release(d3d);
17071 DestroyWindow(window);
17074 static void volume_dxt5_test(void)
17076 IDirect3DVolumeTexture9 *texture;
17077 IDirect3DDevice9 *device;
17078 D3DLOCKED_BOX box;
17079 IDirect3D9 *d3d;
17080 unsigned int i;
17081 ULONG refcount;
17082 DWORD color;
17083 HWND window;
17084 HRESULT hr;
17086 static const char texture_data[] =
17088 /* A 8x4x2 texture consisting of 4 4x4 blocks. The colors of the blocks are red, green, blue and white. */
17089 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
17090 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
17091 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
17092 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
17094 static const struct
17096 struct vec3 position;
17097 struct vec3 texcrd;
17099 quads[] =
17101 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
17102 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
17103 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
17104 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
17106 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
17107 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
17108 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
17109 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
17111 static const DWORD expected_colors[] = {0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff};
17113 window = create_window();
17114 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17115 ok(!!d3d, "Failed to create a D3D object.\n");
17116 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17117 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_DXT5)))
17119 skip("DXT5 volume textures are not supported, skipping test.\n");
17120 goto done;
17122 if (!(device = create_device(d3d, window, window, TRUE)))
17124 skip("Failed to create a D3D device, skipping tests.\n");
17125 goto done;
17128 hr = IDirect3DDevice9_CreateVolumeTexture(device, 8, 4, 2, 1, 0, D3DFMT_DXT5,
17129 D3DPOOL_MANAGED, &texture, NULL);
17130 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
17132 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
17133 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
17134 memcpy(box.pBits, texture_data, sizeof(texture_data));
17135 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
17136 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
17138 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
17139 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
17140 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
17141 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17142 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17143 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17144 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
17145 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17146 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
17147 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17148 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
17149 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
17151 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
17152 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17153 hr = IDirect3DDevice9_BeginScene(device);
17154 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17155 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
17156 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17157 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
17158 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17159 hr = IDirect3DDevice9_EndScene(device);
17160 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17162 for (i = 0; i < 4; i++)
17164 color = getPixelColor(device, 80 + 160 * i, 240);
17165 ok (color_match(color, expected_colors[i], 1),
17166 "Expected color 0x%08x, got 0x%08x, case %u.\n", expected_colors[i], color, i);
17169 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17170 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17171 IDirect3DVolumeTexture9_Release(texture);
17172 refcount = IDirect3DDevice9_Release(device);
17173 ok(!refcount, "Device has %u references left.\n", refcount);
17174 done:
17175 IDirect3D9_Release(d3d);
17176 DestroyWindow(window);
17179 static void volume_v16u16_test(void)
17181 IDirect3DVolumeTexture9 *texture;
17182 IDirect3DPixelShader9 *shader;
17183 IDirect3DDevice9 *device;
17184 D3DLOCKED_BOX box;
17185 IDirect3D9 *d3d;
17186 unsigned int i;
17187 ULONG refcount;
17188 D3DCAPS9 caps;
17189 SHORT *texel;
17190 DWORD color;
17191 HWND window;
17192 HRESULT hr;
17194 static const struct
17196 struct vec3 position;
17197 struct vec3 texcrd;
17199 quads[] =
17201 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
17202 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
17203 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
17204 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
17206 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
17207 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
17208 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
17209 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
17211 static const DWORD shader_code[] =
17213 0xffff0101, /* ps_1_1 */
17214 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, */
17215 0x3f000000, 0x3f000000, /* 0.5, 0.5 */
17216 0x00000042, 0xb00f0000, /* tex t0 */
17217 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
17218 0x0000ffff /* end */
17221 window = create_window();
17222 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17223 ok(!!d3d, "Failed to create a D3D object.\n");
17224 if (!(device = create_device(d3d, window, window, TRUE)))
17226 skip("Failed to create a D3D device, skipping tests.\n");
17227 goto done;
17230 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17231 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17232 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
17234 skip("No ps_1_1 support, skipping tests.\n");
17235 IDirect3DDevice9_Release(device);
17236 goto done;
17238 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17239 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_V16U16)))
17241 skip("Volume V16U16 textures are not supported, skipping test.\n");
17242 IDirect3DDevice9_Release(device);
17243 goto done;
17246 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
17247 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
17248 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
17249 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
17250 hr = IDirect3DDevice9_SetPixelShader(device, shader);
17251 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
17252 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
17253 ok(SUCCEEDED(hr), "Failed to set filter, hr %#x.\n", hr);
17255 for (i = 0; i < 2; i++)
17257 D3DPOOL pool;
17259 if (i)
17260 pool = D3DPOOL_SYSTEMMEM;
17261 else
17262 pool = D3DPOOL_MANAGED;
17264 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
17265 pool, &texture, NULL);
17266 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
17268 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
17269 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
17271 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 0 * box.SlicePitch);
17272 texel[0] = 32767;
17273 texel[1] = 32767;
17274 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 0 * box.SlicePitch);
17275 texel[0] = -32768;
17276 texel[1] = 0;
17277 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 1 * box.SlicePitch);
17278 texel[0] = -16384;
17279 texel[1] = 16384;
17280 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 1 * box.SlicePitch);
17281 texel[0] = 0;
17282 texel[1] = 0;
17284 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
17285 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
17287 if (i)
17289 IDirect3DVolumeTexture9 *texture2;
17291 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
17292 D3DPOOL_DEFAULT, &texture2, NULL);
17293 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
17295 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture,
17296 (IDirect3DBaseTexture9 *)texture2);
17297 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17299 IDirect3DVolumeTexture9_Release(texture);
17300 texture = texture2;
17303 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
17304 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17306 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
17307 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17308 hr = IDirect3DDevice9_BeginScene(device);
17309 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17310 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
17311 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17312 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
17313 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17314 hr = IDirect3DDevice9_EndScene(device);
17315 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17317 color = getPixelColor(device, 120, 160);
17318 ok (color_match(color, 0x000080ff, 2),
17319 "Expected color 0x000080ff, got 0x%08x, V16U16 input -32768, 0.\n", color);
17320 color = getPixelColor(device, 120, 400);
17321 ok (color_match(color, 0x00ffffff, 2),
17322 "Expected color 0x00ffffff, got 0x%08x, V16U16 input 32767, 32767.\n", color);
17323 color = getPixelColor(device, 360, 160);
17324 ok (color_match(color, 0x007f7fff, 2),
17325 "Expected color 0x007f7fff, got 0x%08x, V16U16 input 0, 0.\n", color);
17326 color = getPixelColor(device, 360, 400);
17327 ok (color_match(color, 0x0040c0ff, 2),
17328 "Expected color 0x0040c0ff, got 0x%08x, V16U16 input -16384, 16384.\n", color);
17330 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17331 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17333 IDirect3DVolumeTexture9_Release(texture);
17336 IDirect3DPixelShader9_Release(shader);
17337 refcount = IDirect3DDevice9_Release(device);
17338 ok(!refcount, "Device has %u references left.\n", refcount);
17339 done:
17340 IDirect3D9_Release(d3d);
17341 DestroyWindow(window);
17344 static void add_dirty_rect_test_draw(IDirect3DDevice9 *device)
17346 HRESULT hr;
17347 static const struct
17349 struct vec3 position;
17350 struct vec2 texcoord;
17352 quad[] =
17354 {{-1.0, -1.0, 0.0}, {0.0, 0.0}},
17355 {{-1.0, 1.0, 0.0}, {0.0, 1.0}},
17356 {{ 1.0, -1.0, 0.0}, {1.0, 0.0}},
17357 {{ 1.0, 1.0, 0.0}, {1.0, 1.0}},
17360 hr = IDirect3DDevice9_BeginScene(device);
17361 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17362 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad, sizeof(*quad));
17363 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17364 hr = IDirect3DDevice9_EndScene(device);
17365 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17368 static void add_dirty_rect_test(void)
17370 HRESULT hr;
17371 IDirect3DTexture9 *tex_dst1, *tex_dst2, *tex_src_red, *tex_src_green,
17372 *tex_managed, *tex_dynamic;
17373 IDirect3DSurface9 *surface_dst2, *surface_src_green, *surface_src_red,
17374 *surface_managed0, *surface_managed1, *surface_dynamic;
17375 IDirect3DDevice9 *device;
17376 IDirect3D9 *d3d;
17377 unsigned int i;
17378 ULONG refcount;
17379 DWORD *texel;
17380 HWND window;
17381 D3DLOCKED_RECT locked_rect;
17382 static const RECT part_rect = {96, 96, 160, 160};
17383 DWORD color;
17385 window = create_window();
17386 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17387 ok(!!d3d, "Failed to create a D3D object.\n");
17388 if (!(device = create_device(d3d, window, window, TRUE)))
17390 skip("Failed to create a D3D device, skipping tests.\n");
17391 IDirect3D9_Release(d3d);
17392 DestroyWindow(window);
17393 return;
17396 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17397 D3DPOOL_DEFAULT, &tex_dst1, NULL);
17398 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17399 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17400 D3DPOOL_DEFAULT, &tex_dst2, NULL);
17401 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17402 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17403 D3DPOOL_SYSTEMMEM, &tex_src_red, NULL);
17404 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17405 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17406 D3DPOOL_SYSTEMMEM, &tex_src_green, NULL);
17407 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17408 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 2, 0, D3DFMT_X8R8G8B8,
17409 D3DPOOL_MANAGED, &tex_managed, NULL);
17410 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17411 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, D3DUSAGE_DYNAMIC,
17412 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex_dynamic, NULL);
17413 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17415 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dst2, 0, &surface_dst2);
17416 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17417 hr = IDirect3DTexture9_GetSurfaceLevel(tex_src_green, 0, &surface_src_green);
17418 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17419 hr = IDirect3DTexture9_GetSurfaceLevel(tex_src_red, 0, &surface_src_red);
17420 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17421 hr = IDirect3DTexture9_GetSurfaceLevel(tex_managed, 0, &surface_managed0);
17422 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17423 hr = IDirect3DTexture9_GetSurfaceLevel(tex_managed, 1, &surface_managed1);
17424 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17425 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dynamic, 0, &surface_dynamic);
17426 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17428 fill_surface(surface_src_red, 0x00ff0000, 0);
17429 fill_surface(surface_src_green, 0x0000ff00, 0);
17431 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
17432 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
17433 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17434 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17435 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
17436 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17437 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
17438 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
17440 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17441 (IDirect3DBaseTexture9 *)tex_dst1);
17442 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17444 /* The second UpdateTexture call writing to tex_dst2 is ignored because tex_src_green is not dirty. */
17445 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_red,
17446 (IDirect3DBaseTexture9 *)tex_dst2);
17447 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17448 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17449 (IDirect3DBaseTexture9 *)tex_dst2);
17450 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17452 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst1);
17453 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17454 add_dirty_rect_test_draw(device);
17455 color = getPixelColor(device, 320, 240);
17456 ok(color_match(color, 0x0000ff00, 1),
17457 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17458 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17459 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17461 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst2);
17462 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17463 add_dirty_rect_test_draw(device);
17464 color = getPixelColor(device, 320, 240);
17465 todo_wine ok(color_match(color, 0x00ff0000, 1),
17466 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17467 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17468 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17470 /* AddDirtyRect on the destination is ignored. */
17471 hr = IDirect3DTexture9_AddDirtyRect(tex_dst2, &part_rect);
17472 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17473 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17474 (IDirect3DBaseTexture9 *)tex_dst2);
17475 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17476 add_dirty_rect_test_draw(device);
17477 color = getPixelColor(device, 320, 240);
17478 todo_wine ok(color_match(color, 0x00ff0000, 1),
17479 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17480 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17481 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17483 hr = IDirect3DTexture9_AddDirtyRect(tex_dst2, NULL);
17484 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17485 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17486 (IDirect3DBaseTexture9 *)tex_dst2);
17487 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17488 add_dirty_rect_test_draw(device);
17489 color = getPixelColor(device, 320, 240);
17490 todo_wine ok(color_match(color, 0x00ff0000, 1),
17491 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17492 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17493 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17495 /* AddDirtyRect on the source makes UpdateTexture work. Partial rectangle
17496 * tracking is supported. */
17497 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, &part_rect);
17498 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17499 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17500 (IDirect3DBaseTexture9 *)tex_dst2);
17501 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17502 add_dirty_rect_test_draw(device);
17503 color = getPixelColor(device, 320, 240);
17504 ok(color_match(color, 0x0000ff00, 1),
17505 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17506 color = getPixelColor(device, 1, 1);
17507 todo_wine ok(color_match(color, 0x00ff0000, 1),
17508 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17509 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17510 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17512 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, NULL);
17513 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17514 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17515 (IDirect3DBaseTexture9 *)tex_dst2);
17516 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17517 add_dirty_rect_test_draw(device);
17518 color = getPixelColor(device, 1, 1);
17519 ok(color_match(color, 0x0000ff00, 1),
17520 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17522 /* Locks with NO_DIRTY_UPDATE are ignored. */
17523 fill_surface(surface_src_green, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE);
17524 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17525 (IDirect3DBaseTexture9 *)tex_dst2);
17526 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17527 add_dirty_rect_test_draw(device);
17528 color = getPixelColor(device, 320, 240);
17529 todo_wine ok(color_match(color, 0x0000ff00, 1),
17530 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17531 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17532 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17534 /* Readonly maps write to D3DPOOL_SYSTEMMEM, but don't record a dirty rectangle. */
17535 fill_surface(surface_src_green, 0x000000ff, D3DLOCK_READONLY);
17536 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17537 (IDirect3DBaseTexture9 *)tex_dst2);
17538 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17539 add_dirty_rect_test_draw(device);
17540 color = getPixelColor(device, 320, 240);
17541 todo_wine ok(color_match(color, 0x0000ff00, 1),
17542 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17543 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17544 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17546 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, NULL);
17547 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17548 (IDirect3DBaseTexture9 *)tex_dst2);
17549 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17550 add_dirty_rect_test_draw(device);
17551 color = getPixelColor(device, 320, 240);
17552 ok(color_match(color, 0x000000ff, 1),
17553 "Expected color 0x000000ff, 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 /* Maps without either of these flags record a dirty rectangle. */
17558 fill_surface(surface_src_green, 0x00ffffff, 0);
17559 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17560 (IDirect3DBaseTexture9 *)tex_dst2);
17561 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17562 add_dirty_rect_test_draw(device);
17563 color = getPixelColor(device, 320, 240);
17564 ok(color_match(color, 0x00ffffff, 1),
17565 "Expected color 0x00ffffff, got 0x%08x.\n", color);
17566 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17567 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17569 /* Partial LockRect works just like a partial AddDirtyRect call. */
17570 hr = IDirect3DTexture9_LockRect(tex_src_green, 0, &locked_rect, &part_rect, 0);
17571 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17572 texel = locked_rect.pBits;
17573 for (i = 0; i < 64; i++)
17574 texel[i] = 0x00ff00ff;
17575 for (i = 1; i < 64; i++)
17576 memcpy((BYTE *)locked_rect.pBits + i * locked_rect.Pitch, locked_rect.pBits, locked_rect.Pitch);
17577 hr = IDirect3DTexture9_UnlockRect(tex_src_green, 0);
17578 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17579 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17580 (IDirect3DBaseTexture9 *)tex_dst2);
17581 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17582 add_dirty_rect_test_draw(device);
17583 color = getPixelColor(device, 320, 240);
17584 ok(color_match(color, 0x00ff00ff, 1),
17585 "Expected color 0x00ff00ff, got 0x%08x.\n", color);
17586 color = getPixelColor(device, 1, 1);
17587 ok(color_match(color, 0x00ffffff, 1),
17588 "Expected color 0x00ffffff, got 0x%08x.\n", color);
17589 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17590 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17592 fill_surface(surface_src_red, 0x00ff0000, 0);
17593 fill_surface(surface_src_green, 0x0000ff00, 0);
17595 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17596 (IDirect3DBaseTexture9 *)tex_dst1);
17597 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17598 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst1);
17599 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17600 add_dirty_rect_test_draw(device);
17601 color = getPixelColor(device, 320, 240);
17602 ok(color_match(color, 0x0000ff00, 1),
17603 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17604 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17605 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17607 /* UpdateSurface ignores the missing dirty marker. */
17608 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_red,
17609 (IDirect3DBaseTexture9 *)tex_dst2);
17610 hr = IDirect3DDevice9_UpdateSurface(device, surface_src_green, NULL, surface_dst2, NULL);
17611 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
17612 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst2);
17613 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17614 add_dirty_rect_test_draw(device);
17615 color = getPixelColor(device, 320, 240);
17616 ok(color_match(color, 0x0000ff00, 1),
17617 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17618 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17619 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17621 /* Tests with managed textures. */
17622 fill_surface(surface_managed0, 0x00ff0000, 0);
17623 fill_surface(surface_managed1, 0x00ff0000, 0);
17624 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_managed);
17625 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17626 add_dirty_rect_test_draw(device);
17627 color = getPixelColor(device, 320, 240);
17628 ok(color_match(color, 0x00ff0000, 1),
17629 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17630 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17631 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17632 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
17633 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
17634 add_dirty_rect_test_draw(device);
17635 color = getPixelColor(device, 320, 240);
17636 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
17637 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17638 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17640 /* Managed textures also honor D3DLOCK_NO_DIRTY_UPDATE. */
17641 fill_surface(surface_managed0, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE);
17642 fill_surface(surface_managed1, 0x000000ff, D3DLOCK_NO_DIRTY_UPDATE);
17643 add_dirty_rect_test_draw(device);
17644 color = getPixelColor(device, 320, 240);
17645 ok(color_match(color, 0x00ff0000, 1),
17646 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17647 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17648 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17649 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
17650 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
17651 add_dirty_rect_test_draw(device);
17652 color = getPixelColor(device, 320, 240);
17653 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
17654 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17655 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17657 /* AddDirtyRect uploads the new contents.
17658 * Side note, not tested in the test: Partial surface updates work, and two separate
17659 * dirty rectangles are tracked individually. Tested on Nvidia Kepler, other drivers
17660 * untested. */
17661 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
17662 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17663 add_dirty_rect_test_draw(device);
17664 color = getPixelColor(device, 320, 240);
17665 ok(color_match(color, 0x0000ff00, 1),
17666 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17667 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17668 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17669 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
17670 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
17671 add_dirty_rect_test_draw(device);
17672 color = getPixelColor(device, 320, 240);
17673 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
17674 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17675 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17677 /* So does EvictManagedResources. */
17678 fill_surface(surface_managed0, 0x00ffff00, D3DLOCK_NO_DIRTY_UPDATE);
17679 fill_surface(surface_managed1, 0x00ff00ff, D3DLOCK_NO_DIRTY_UPDATE);
17680 hr = IDirect3DDevice9_EvictManagedResources(device);
17681 ok(SUCCEEDED(hr), "Failed to evict managed resources, hr %#x.\n", hr);
17682 add_dirty_rect_test_draw(device);
17683 color = getPixelColor(device, 320, 240);
17684 ok(color_match(color, 0x00ff00ff, 1), "Got unexpected color 0x%08x.\n", color);
17685 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17686 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17687 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
17688 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
17689 add_dirty_rect_test_draw(device);
17690 color = getPixelColor(device, 320, 240);
17691 ok(color_match(color, 0x00ffff00, 1), "Got unexpected color 0x%08x.\n", color);
17692 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17693 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17695 /* Tests with dynamic textures */
17696 fill_surface(surface_dynamic, 0x0000ffff, 0);
17697 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dynamic);
17698 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17699 add_dirty_rect_test_draw(device);
17700 color = getPixelColor(device, 320, 240);
17701 ok(color_match(color, 0x0000ffff, 1),
17702 "Expected color 0x0000ffff, got 0x%08x.\n", color);
17703 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17704 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17706 /* Dynamic textures don't honor D3DLOCK_NO_DIRTY_UPDATE. */
17707 fill_surface(surface_dynamic, 0x00ffff00, D3DLOCK_NO_DIRTY_UPDATE);
17708 add_dirty_rect_test_draw(device);
17709 color = getPixelColor(device, 320, 240);
17710 ok(color_match(color, 0x00ffff00, 1),
17711 "Expected color 0x00ffff00, got 0x%08x.\n", color);
17712 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17713 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17715 /* AddDirtyRect on a locked texture is allowed. */
17716 hr = IDirect3DTexture9_LockRect(tex_src_red, 0, &locked_rect, NULL, 0);
17717 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17718 hr = IDirect3DTexture9_AddDirtyRect(tex_src_red, NULL);
17719 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17720 hr = IDirect3DTexture9_UnlockRect(tex_src_red, 0);
17721 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17723 /* Redundant AddDirtyRect calls are ok. */
17724 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
17725 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17726 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
17727 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17729 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
17730 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17731 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
17732 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17733 IDirect3DSurface9_Release(surface_dst2);
17734 IDirect3DSurface9_Release(surface_managed1);
17735 IDirect3DSurface9_Release(surface_managed0);
17736 IDirect3DSurface9_Release(surface_src_red);
17737 IDirect3DSurface9_Release(surface_src_green);
17738 IDirect3DSurface9_Release(surface_dynamic);
17739 IDirect3DTexture9_Release(tex_src_red);
17740 IDirect3DTexture9_Release(tex_src_green);
17741 IDirect3DTexture9_Release(tex_dst1);
17742 IDirect3DTexture9_Release(tex_dst2);
17743 IDirect3DTexture9_Release(tex_managed);
17744 IDirect3DTexture9_Release(tex_dynamic);
17745 refcount = IDirect3DDevice9_Release(device);
17746 ok(!refcount, "Device has %u references left.\n", refcount);
17747 IDirect3D9_Release(d3d);
17748 DestroyWindow(window);
17751 static void test_per_stage_constant(void)
17753 IDirect3DDevice9 *device;
17754 IDirect3D9 *d3d;
17755 D3DCOLOR color;
17756 ULONG refcount;
17757 D3DCAPS9 caps;
17758 HWND window;
17759 HRESULT hr;
17761 static const struct
17763 struct vec3 position;
17764 D3DCOLOR diffuse;
17766 quad[] =
17768 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
17769 {{-1.0f, 1.0f, 0.1f}, 0xffff0000},
17770 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
17771 {{ 1.0f, 1.0f, 0.1f}, 0xffff0000},
17774 window = create_window();
17775 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17776 ok(!!d3d, "Failed to create a D3D object.\n");
17777 if (!(device = create_device(d3d, window, window, TRUE)))
17779 skip("Failed to create a D3D device, skipping tests.\n");
17780 goto done;
17783 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17784 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17785 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_PERSTAGECONSTANT))
17787 skip("Per-stage constants not supported, skipping tests.\n");
17788 IDirect3DDevice9_Release(device);
17789 goto done;
17792 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
17793 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
17794 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
17795 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17796 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
17797 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17798 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
17799 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17800 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
17801 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17803 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_CONSTANT, 0x80a1b2c3);
17804 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17805 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT);
17806 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17807 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17808 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17810 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17811 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17813 hr = IDirect3DDevice9_BeginScene(device);
17814 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17815 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17816 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17817 hr = IDirect3DDevice9_EndScene(device);
17818 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17820 color = getPixelColor(device, 320, 240);
17821 ok(color_match(color, 0x00a1b2c3, 1), "Got unexpected color 0x%08x.\n", color);
17822 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17823 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17825 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT | D3DTA_COMPLEMENT);
17826 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17828 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17829 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17831 hr = IDirect3DDevice9_BeginScene(device);
17832 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17833 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17834 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17835 hr = IDirect3DDevice9_EndScene(device);
17836 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17838 color = getPixelColor(device, 320, 240);
17839 ok(color_match(color, 0x005e4d3c, 1), "Got unexpected color 0x%08x.\n", color);
17840 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17841 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17843 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT | D3DTA_ALPHAREPLICATE);
17844 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17846 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17847 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17849 hr = IDirect3DDevice9_BeginScene(device);
17850 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17851 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17852 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17853 hr = IDirect3DDevice9_EndScene(device);
17854 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17856 color = getPixelColor(device, 320, 240);
17857 ok(color_match(color, 0x00808080, 1), "Got unexpected color 0x%08x.\n", color);
17858 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17859 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17861 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_CONSTANT);
17862 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17863 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
17864 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17865 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CURRENT);
17866 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17868 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17869 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17871 hr = IDirect3DDevice9_BeginScene(device);
17872 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17873 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17874 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17875 hr = IDirect3DDevice9_EndScene(device);
17876 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17878 color = getPixelColor(device, 320, 240);
17879 ok(color_match(color, 0x0080007f, 1), "Got unexpected color 0x%08x.\n", color);
17880 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17881 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17883 refcount = IDirect3DDevice9_Release(device);
17884 ok(!refcount, "Device has %u references left.\n", refcount);
17885 done:
17886 IDirect3D9_Release(d3d);
17887 DestroyWindow(window);
17890 static void test_3dc_formats(void)
17892 static const char ati1n_data[] =
17894 /* A 4x4 texture with the color component at 50%. */
17895 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
17897 static const char ati2n_data[] =
17899 /* A 8x4 texture consisting of 2 4x4 blocks. The first block has 50% first color component,
17900 * 0% second component. Second block is the opposite. */
17901 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
17902 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
17904 static const struct
17906 struct vec3 position;
17907 struct vec2 texcoord;
17909 quads[] =
17911 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
17912 {{-1.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
17913 {{ 0.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
17914 {{ 0.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
17916 {{ 0.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
17917 {{ 0.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
17918 {{ 1.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
17919 {{ 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
17921 static const DWORD ati1n_fourcc = MAKEFOURCC('A','T','I','1');
17922 static const DWORD ati2n_fourcc = MAKEFOURCC('A','T','I','2');
17923 static const struct
17925 struct vec2 position;
17926 D3DCOLOR amd_r500;
17927 D3DCOLOR amd_r600;
17928 D3DCOLOR nvidia_old;
17929 D3DCOLOR nvidia_new;
17931 expected_colors[] =
17933 {{ 80, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
17934 {{240, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
17935 {{400, 240}, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff},
17936 {{560, 240}, 0x007f00ff, 0x007f00ff, 0x007f00ff, 0x007f00ff},
17938 IDirect3D9 *d3d;
17939 IDirect3DDevice9 *device;
17940 IDirect3DTexture9 *ati1n_texture, *ati2n_texture;
17941 D3DCAPS9 caps;
17942 D3DLOCKED_RECT rect;
17943 D3DCOLOR color;
17944 ULONG refcount;
17945 HWND window;
17946 HRESULT hr;
17947 unsigned int i;
17949 window = create_window();
17950 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17951 ok(!!d3d, "Failed to create a D3D object.\n");
17952 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17953 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati1n_fourcc)))
17955 skip("ATI1N textures are not supported, skipping test.\n");
17956 goto done;
17958 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17959 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati2n_fourcc)))
17961 skip("ATI2N textures are not supported, skipping test.\n");
17962 goto done;
17964 if (!(device = create_device(d3d, window, window, TRUE)))
17966 skip("Failed to create a D3D device, skipping tests.\n");
17967 goto done;
17969 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17970 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17971 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
17973 skip("D3DTA_TEMP not supported, skipping tests.\n");
17974 IDirect3DDevice9_Release(device);
17975 goto done;
17978 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, ati1n_fourcc,
17979 D3DPOOL_MANAGED, &ati1n_texture, NULL);
17980 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17982 hr = IDirect3DTexture9_LockRect(ati1n_texture, 0, &rect, NULL, 0);
17983 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17984 memcpy(rect.pBits, ati1n_data, sizeof(ati1n_data));
17985 hr = IDirect3DTexture9_UnlockRect(ati1n_texture, 0);
17986 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17988 hr = IDirect3DDevice9_CreateTexture(device, 8, 4, 1, 0, ati2n_fourcc,
17989 D3DPOOL_MANAGED, &ati2n_texture, NULL);
17990 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17992 hr = IDirect3DTexture9_LockRect(ati2n_texture, 0, &rect, NULL, 0);
17993 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17994 memcpy(rect.pBits, ati2n_data, sizeof(ati2n_data));
17995 hr = IDirect3DTexture9_UnlockRect(ati2n_texture, 0);
17996 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17998 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0));
17999 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
18000 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
18001 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
18002 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
18003 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
18004 /* The temporary register is initialized to 0. */
18005 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TEMP);
18006 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
18007 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
18008 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#x.\n", hr);
18009 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
18010 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#x.\n", hr);
18011 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
18012 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
18013 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
18014 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
18016 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
18017 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18018 hr = IDirect3DDevice9_BeginScene(device);
18019 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18020 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)ati1n_texture);
18021 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
18022 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
18023 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18024 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)ati2n_texture);
18025 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
18026 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
18027 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18028 hr = IDirect3DDevice9_EndScene(device);
18029 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18031 for (i = 0; i < 4; ++i)
18033 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
18034 ok (color_match(color, expected_colors[i].amd_r500, 1)
18035 || color_match(color, expected_colors[i].amd_r600, 1)
18036 || color_match(color, expected_colors[i].nvidia_old, 1)
18037 || color_match(color, expected_colors[i].nvidia_new, 1),
18038 "Got unexpected color 0x%08x, case %u.\n", color, i);
18041 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18042 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18043 IDirect3DTexture9_Release(ati2n_texture);
18044 IDirect3DTexture9_Release(ati1n_texture);
18045 refcount = IDirect3DDevice9_Release(device);
18046 ok(!refcount, "Device has %u references left.\n", refcount);
18048 done:
18049 IDirect3D9_Release(d3d);
18050 DestroyWindow(window);
18053 static void test_fog_interpolation(void)
18055 HRESULT hr;
18056 IDirect3DDevice9 *device;
18057 IDirect3D9 *d3d;
18058 ULONG refcount;
18059 HWND window;
18060 D3DCOLOR color;
18061 static const struct
18063 struct vec3 position;
18064 D3DCOLOR diffuse;
18065 D3DCOLOR specular;
18067 quad[] =
18069 {{-1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff000000},
18070 {{-1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff000000},
18071 {{ 1.0f, -1.0f, 1.0f}, 0xffff0000, 0x00000000},
18072 {{ 1.0f, 1.0f, 1.0f}, 0xffff0000, 0x00000000},
18074 union
18076 DWORD d;
18077 float f;
18078 } conv;
18079 unsigned int i;
18080 static const struct
18082 D3DFOGMODE vfog, tfog;
18083 D3DSHADEMODE shade;
18084 D3DCOLOR middle_color;
18085 BOOL todo;
18087 tests[] =
18089 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, FALSE},
18090 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, FALSE},
18091 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, TRUE},
18092 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, TRUE},
18093 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
18094 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
18095 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
18096 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
18098 static const D3DMATRIX ident_mat =
18100 1.0f, 0.0f, 0.0f, 0.0f,
18101 0.0f, 1.0f, 0.0f, 0.0f,
18102 0.0f, 0.0f, 1.0f, 0.0f,
18103 0.0f, 0.0f, 0.0f, 1.0f
18104 }}};
18105 D3DCAPS9 caps;
18107 window = create_window();
18108 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18109 ok(!!d3d, "Failed to create a D3D object.\n");
18111 if (!(device = create_device(d3d, window, window, TRUE)))
18113 skip("Failed to create a D3D device, skipping tests.\n");
18114 IDirect3D9_Release(d3d);
18115 DestroyWindow(window);
18116 return;
18119 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18120 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18121 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
18122 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
18124 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
18125 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
18126 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18127 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18128 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
18129 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18130 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
18131 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18132 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
18133 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18134 conv.f = 5.0;
18135 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGDENSITY, conv.d);
18136 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18138 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
18139 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
18140 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
18141 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
18142 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x000000ff);
18143 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18145 /* Some of the tests seem to depend on the projection matrix explicitly
18146 * being set to an identity matrix, even though that's the default.
18147 * (AMD Radeon X1600, AMD Radeon HD 6310, Windows 7). Without this,
18148 * the drivers seem to use a static z = 1.0 input for the fog equation.
18149 * The input value is independent of the actual z and w component of
18150 * the vertex position. */
18151 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
18152 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
18154 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
18156 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
18157 continue;
18159 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00808080, 0.0f, 0);
18160 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18162 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shade);
18163 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18164 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
18165 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18166 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
18167 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18168 hr = IDirect3DDevice9_BeginScene(device);
18169 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18170 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18171 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18172 hr = IDirect3DDevice9_EndScene(device);
18173 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18175 color = getPixelColor(device, 0, 240);
18176 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
18177 color = getPixelColor(device, 320, 240);
18178 todo_wine_if (tests[i].todo)
18179 ok(color_match(color, tests[i].middle_color, 2),
18180 "Got unexpected color 0x%08x, case %u.\n", color, i);
18181 color = getPixelColor(device, 639, 240);
18182 ok(color_match(color, 0x0000fd02, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
18183 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18184 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18187 refcount = IDirect3DDevice9_Release(device);
18188 ok(!refcount, "Device has %u references left.\n", refcount);
18189 IDirect3D9_Release(d3d);
18190 DestroyWindow(window);
18193 static void test_negative_fixedfunction_fog(void)
18195 HRESULT hr;
18196 IDirect3DDevice9 *device;
18197 IDirect3D9 *d3d;
18198 ULONG refcount;
18199 HWND window;
18200 D3DCOLOR color;
18201 static const struct
18203 struct vec3 position;
18204 D3DCOLOR diffuse;
18206 quad[] =
18208 {{-1.0f, -1.0f, -0.5f}, 0xffff0000},
18209 {{-1.0f, 1.0f, -0.5f}, 0xffff0000},
18210 {{ 1.0f, -1.0f, -0.5f}, 0xffff0000},
18211 {{ 1.0f, 1.0f, -0.5f}, 0xffff0000},
18213 static const struct
18215 struct vec4 position;
18216 D3DCOLOR diffuse;
18218 tquad[] =
18220 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
18221 {{640.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
18222 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
18223 {{640.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
18225 unsigned int i;
18226 static const D3DMATRIX zero =
18228 1.0f, 0.0f, 0.0f, 0.0f,
18229 0.0f, 1.0f, 0.0f, 0.0f,
18230 0.0f, 0.0f, 0.0f, 0.0f,
18231 0.0f, 0.0f, 0.0f, 1.0f
18232 }}};
18233 /* Needed to make AMD drivers happy. Yeah, it is not supposed to
18234 * have an effect on RHW draws. */
18235 static const D3DMATRIX identity =
18237 1.0f, 0.0f, 0.0f, 0.0f,
18238 0.0f, 1.0f, 0.0f, 0.0f,
18239 0.0f, 0.0f, 1.0f, 0.0f,
18240 0.0f, 0.0f, 0.0f, 1.0f
18241 }}};
18242 static const struct
18244 DWORD pos_type;
18245 const void *quad;
18246 size_t stride;
18247 const D3DMATRIX *matrix;
18248 union
18250 float f;
18251 DWORD d;
18252 } start, end;
18253 D3DFOGMODE vfog, tfog;
18254 DWORD color, color_broken, color_broken2;
18256 tests[] =
18258 /* Run the XYZRHW tests first. Depth clamping is broken after RHW draws on the testbot.
18260 * Geforce8+ GPUs on Windows abs() table fog, everything else does not. */
18261 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, { 0.0f}, {1.0f},
18262 D3DFOG_NONE, D3DFOG_LINEAR, 0x00ff0000, 0x00808000, 0x00808000},
18263 /* r200 GPUs and presumably all d3d8 and older HW clamp the fog
18264 * parameters to 0.0 and 1.0 in the table fog case. */
18265 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, {-1.0f}, {0.0f},
18266 D3DFOG_NONE, D3DFOG_LINEAR, 0x00808000, 0x00ff0000, 0x0000ff00},
18267 /* test_fog_interpolation shows that vertex fog evaluates the fog
18268 * equation in the vertex pipeline. Start = -1.0 && end = 0.0 shows
18269 * that the abs happens before the fog equation is evaluated.
18271 * Vertex fog abs() behavior is the same on all GPUs. */
18272 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
18273 D3DFOG_LINEAR, D3DFOG_NONE, 0x00808000, 0x00808000, 0x00808000},
18274 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, {-1.0f}, {0.0f},
18275 D3DFOG_LINEAR, D3DFOG_NONE, 0x0000ff00, 0x0000ff00, 0x0000ff00},
18276 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
18277 D3DFOG_EXP, D3DFOG_NONE, 0x009b6400, 0x009b6400, 0x009b6400},
18279 D3DCAPS9 caps;
18281 window = create_window();
18282 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18283 ok(!!d3d, "Failed to create a D3D object.\n");
18285 if (!(device = create_device(d3d, window, window, TRUE)))
18287 skip("Failed to create a D3D device, skipping tests.\n");
18288 IDirect3D9_Release(d3d);
18289 DestroyWindow(window);
18290 return;
18293 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18294 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18295 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
18296 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests.\n");
18298 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18299 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18300 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
18301 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18302 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
18303 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18304 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
18305 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18306 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
18307 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
18309 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
18311 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
18312 continue;
18314 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
18315 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18317 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, tests[i].matrix);
18318 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
18319 hr = IDirect3DDevice9_SetFVF(device, tests[i].pos_type | D3DFVF_DIFFUSE);
18320 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
18321 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, tests[i].start.d);
18322 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18323 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, tests[i].end.d);
18324 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18325 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
18326 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18327 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
18328 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18330 hr = IDirect3DDevice9_BeginScene(device);
18331 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18332 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tests[i].quad, tests[i].stride);
18333 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18334 hr = IDirect3DDevice9_EndScene(device);
18335 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18337 color = getPixelColor(device, 320, 240);
18338 ok(color_match(color, tests[i].color, 2) || broken(color_match(color, tests[i].color_broken, 2))
18339 || broken(color_match(color, tests[i].color_broken2, 2)),
18340 "Got unexpected color 0x%08x, case %u.\n", color, i);
18341 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18342 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18345 refcount = IDirect3DDevice9_Release(device);
18346 ok(!refcount, "Device has %u references left.\n", refcount);
18347 IDirect3D9_Release(d3d);
18348 DestroyWindow(window);
18351 static void test_position_index(void)
18353 static const D3DVERTEXELEMENT9 decl_elements[] =
18355 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
18356 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 1},
18357 D3DDECL_END()
18359 /* Declaring (and using) a position1 output semantic in a VS fails at draw time on AMD
18360 * but works on Nvidia.
18361 * MSDN is not consistent on this point. */
18362 static const DWORD vs_code[] =
18364 0xfffe0300, /* vs_3_0 */
18365 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
18366 0x0200001f, 0x80010000, 0x900f0001, /* dcl_position1 v1 */
18367 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position0 o0 */
18368 0x0200001f, 0x80010000, 0xe00f0001, /* dcl_position1 o1 */
18369 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
18370 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
18371 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
18372 0x02000001, 0xe00f0002, 0x90e40001, /* mov o2, v1 */
18373 0x0000ffff /* end */
18375 static const DWORD vs_code_2[] =
18377 0xfffe0300, /* vs_3_0 */
18378 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
18379 0x0200001f, 0x80010000, 0x900f0001, /* dcl_position1 v1 */
18380 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position0 o0 */
18381 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
18382 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
18383 0x02000001, 0xe00f0002, 0x90e40001, /* mov o2, v1 */
18384 0x0000ffff /* end */
18386 static const DWORD ps_code[] =
18388 0xffff0300, /* ps_3_0 */
18389 0x0200001f, 0x80010000, 0x900f0000, /* dcl_position1 v0 */
18390 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
18391 0x0000ffff /* end */
18393 static const DWORD ps_code_2[] =
18395 0xffff0300, /* ps_3_0 */
18396 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
18397 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
18398 0x0000ffff /* end */
18400 /* This one is considered invalid by the native shader assembler. */
18401 static const DWORD ps_code_bad[] =
18403 0xffff0300, /* ps_3_0 */
18404 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
18405 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
18406 0x0000ffff /* end */
18408 static const struct
18410 struct vec3 position;
18411 struct vec3 position1;
18413 quad[] =
18415 {{-1.0f, -1.0f, 0.5f}, {1.0f, 0.0f, 0.0f}},
18416 {{-1.0f, 1.0f, 0.5f}, {1.0f, 0.0f, 0.0f}},
18417 {{ 1.0f, -1.0f, 0.5f}, {0.0f, 1.0f, 0.0f}},
18418 {{ 1.0f, 1.0f, 0.5f}, {0.0f, 1.0f, 0.0f}},
18420 static const struct
18422 struct vec2 position;
18423 D3DCOLOR expected_color;
18424 D3DCOLOR broken_color;
18426 expected_colors[] =
18428 {{ 80, 240}, 0x00df2000, 0x00ff00ff},
18429 {{240, 240}, 0x009f6000, 0x00ff00ff},
18430 {{400, 240}, 0x00609f00, 0x00ff00ff},
18431 {{560, 240}, 0x0020df00, 0x00ff00ff},
18433 IDirect3D9 *d3d;
18434 IDirect3DDevice9 *device;
18435 IDirect3DVertexDeclaration9 *vertex_declaration;
18436 IDirect3DVertexShader9 *vs, *vs2;
18437 IDirect3DPixelShader9 *ps, *ps2;
18438 D3DCAPS9 caps;
18439 D3DCOLOR color;
18440 ULONG refcount;
18441 HWND window;
18442 HRESULT hr;
18443 unsigned int i;
18445 window = create_window();
18446 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18447 ok(!!d3d, "Failed to create a D3D object.\n");
18448 if (!(device = create_device(d3d, window, window, TRUE)))
18450 skip("Failed to create a D3D device, skipping tests.\n");
18451 goto done;
18454 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18455 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18456 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0)
18457 || caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
18459 skip("Shader model 3.0 unsupported, skipping tests.\n");
18460 IDirect3DDevice9_Release(device);
18461 goto done;
18464 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
18465 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed, hr %#x\n", hr);
18467 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
18468 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x\n", hr);
18470 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
18471 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
18472 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code_2, &vs2);
18473 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
18475 hr = IDirect3DDevice9_SetVertexShader(device, vs);
18476 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
18478 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_bad, &ps);
18479 ok(hr == D3DERR_INVALIDCALL, "CreatePixelShader returned hr %#x.\n", hr);
18481 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
18482 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
18483 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_2, &ps2);
18484 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
18486 hr = IDirect3DDevice9_SetPixelShader(device, ps);
18487 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18489 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
18490 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18491 hr = IDirect3DDevice9_BeginScene(device);
18492 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18493 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18494 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18495 hr = IDirect3DDevice9_EndScene(device);
18496 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18498 for (i = 0; i < sizeof(expected_colors) / sizeof(expected_colors[0]); ++i)
18500 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
18501 ok (color_match(color, expected_colors[i].expected_color, 1)
18502 || broken(color_match(color, expected_colors[i].broken_color, 1)),
18503 "Got unexpected color 0x%08x, case %u.\n", color, i);
18506 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
18507 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18509 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
18510 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18511 hr = IDirect3DDevice9_BeginScene(device);
18512 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18513 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18514 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18515 hr = IDirect3DDevice9_EndScene(device);
18516 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18518 for (i = 0; i < sizeof(expected_colors) / sizeof(expected_colors[0]); ++i)
18520 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
18521 ok (color_match(color, expected_colors[i].expected_color, 1)
18522 || broken(color_match(color, expected_colors[i].broken_color, 1)),
18523 "Got unexpected color 0x%08x, case %u.\n", color, i);
18526 hr = IDirect3DDevice9_SetVertexShader(device, vs2);
18527 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
18529 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
18530 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18531 hr = IDirect3DDevice9_BeginScene(device);
18532 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18533 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18534 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18535 hr = IDirect3DDevice9_EndScene(device);
18536 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18538 for (i = 0; i < sizeof(expected_colors) / sizeof(expected_colors[0]); ++i)
18540 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
18541 ok (color_match(color, expected_colors[i].expected_color, 1),
18542 "Got unexpected color 0x%08x, case %u.\n", color, i);
18545 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18546 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18548 IDirect3DPixelShader9_Release(ps2);
18549 IDirect3DPixelShader9_Release(ps);
18550 IDirect3DVertexShader9_Release(vs2);
18551 IDirect3DVertexShader9_Release(vs);
18552 IDirect3DVertexDeclaration9_Release(vertex_declaration);
18553 refcount = IDirect3DDevice9_Release(device);
18554 ok(!refcount, "Device has %u references left.\n", refcount);
18556 done:
18557 IDirect3D9_Release(d3d);
18558 DestroyWindow(window);
18561 static void test_table_fog_zw(void)
18563 HRESULT hr;
18564 IDirect3DDevice9 *device;
18565 IDirect3D9 *d3d;
18566 ULONG refcount;
18567 HWND window;
18568 D3DCOLOR color;
18569 D3DCAPS9 caps;
18570 static struct
18572 struct vec4 position;
18573 D3DCOLOR diffuse;
18575 quad[] =
18577 {{ 0.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
18578 {{640.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
18579 {{ 0.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
18580 {{640.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
18582 static const D3DMATRIX identity =
18584 1.0f, 0.0f, 0.0f, 0.0f,
18585 0.0f, 1.0f, 0.0f, 0.0f,
18586 0.0f, 0.0f, 1.0f, 0.0f,
18587 0.0f, 0.0f, 0.0f, 1.0f
18588 }}};
18589 static const struct
18591 float z, w;
18592 D3DZBUFFERTYPE z_test;
18593 D3DCOLOR color;
18595 tests[] =
18597 {0.7f, 0.0f, D3DZB_TRUE, 0x004cb200},
18598 {0.7f, 0.0f, D3DZB_FALSE, 0x004cb200},
18599 {0.7f, 0.3f, D3DZB_TRUE, 0x004cb200},
18600 {0.7f, 0.3f, D3DZB_FALSE, 0x004cb200},
18601 {0.7f, 3.0f, D3DZB_TRUE, 0x004cb200},
18602 {0.7f, 3.0f, D3DZB_FALSE, 0x004cb200},
18603 {0.3f, 0.0f, D3DZB_TRUE, 0x00b24c00},
18604 {0.3f, 0.0f, D3DZB_FALSE, 0x00b24c00},
18606 unsigned int i;
18608 window = create_window();
18609 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18610 ok(!!d3d, "Failed to create a D3D object.\n");
18612 if (!(device = create_device(d3d, window, window, TRUE)))
18614 skip("Failed to create a D3D device, skipping tests.\n");
18615 IDirect3D9_Release(d3d);
18616 DestroyWindow(window);
18617 return;
18620 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18621 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18622 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
18624 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping POSITIONT table fog test.\n");
18625 goto done;
18628 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18629 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18630 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
18631 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18632 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
18633 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18634 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
18635 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
18636 /* Work around an AMD Windows driver bug. Needs a proj matrix applied redundantly. */
18637 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
18638 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
18639 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
18640 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18641 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
18642 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
18644 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
18646 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
18647 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18649 quad[0].position.z = tests[i].z;
18650 quad[1].position.z = tests[i].z;
18651 quad[2].position.z = tests[i].z;
18652 quad[3].position.z = tests[i].z;
18653 quad[0].position.w = tests[i].w;
18654 quad[1].position.w = tests[i].w;
18655 quad[2].position.w = tests[i].w;
18656 quad[3].position.w = tests[i].w;
18657 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, tests[i].z_test);
18658 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18660 hr = IDirect3DDevice9_BeginScene(device);
18661 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18662 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
18663 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18664 hr = IDirect3DDevice9_EndScene(device);
18665 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18667 color = getPixelColor(device, 320, 240);
18668 ok(color_match(color, tests[i].color, 2),
18669 "Got unexpected color 0x%08x, expected 0x%08x, case %u.\n", color, tests[i].color, i);
18670 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18671 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18674 done:
18675 refcount = IDirect3DDevice9_Release(device);
18676 ok(!refcount, "Device has %u references left.\n", refcount);
18677 IDirect3D9_Release(d3d);
18678 DestroyWindow(window);
18681 static void test_signed_formats(void)
18683 IDirect3DDevice9 *device;
18684 HWND window;
18685 HRESULT hr;
18686 unsigned int i, j, x, y;
18687 IDirect3DTexture9 *texture, *texture_sysmem;
18688 IDirect3DSurface9 *src_surface, *dst_surface;
18689 D3DLOCKED_RECT locked_rect;
18690 IDirect3DPixelShader9 *shader, *shader_alpha;
18691 IDirect3D9 *d3d;
18692 D3DCOLOR color;
18693 D3DCAPS9 caps;
18694 ULONG refcount;
18696 /* The input data was designed for D3DFMT_L6V5U5 and then transferred
18697 * to the other formats because L6V5U5 is the lowest precision format.
18698 * It tests the extreme values -1.0 (-16) and 1.0 (15) for U/V and
18699 * 0.0 (0) and 1.0 (63) for L, the neutral point 0 as well as -1 and 1.
18700 * Some other intermediate values are tested too. The input value -15
18701 * (min + 1) is tested as well. Unlike what OpenGL 4.4 says in section
18702 * 2.3.4.1, this value does not represent -1.0. In the interest of re-
18703 * using the expected output data the 8 bit and 16 bit values in V8U8
18704 * and V16U16 match (post-normalization) the 5 bit input values. Thus
18705 * -1, 1 and -127 are not tested in V8U8.
18707 * 8 bit specific values like -127 are tested in the Q channel of
18708 * D3DFMT_Q8W8V8U8. Here d3d seems to follow the rules from the GL
18709 * spec. AMD's r200 is broken though and returns a value < -1.0 for
18710 * -128. The difference between using -127 or -128 as the lowest
18711 * possible value gets lost in the slop of 1 though. */
18712 static const USHORT content_v8u8[4][4] =
18714 {0x0000, 0x7f7f, 0x8880, 0x0000},
18715 {0x0080, 0x8000, 0x7f00, 0x007f},
18716 {0x193b, 0xe8c8, 0x0808, 0xf8f8},
18717 {0x4444, 0xc0c0, 0xa066, 0x22e0},
18719 static const DWORD content_v16u16[4][4] =
18721 {0x00000000, 0x7fff7fff, 0x88008000, 0x00000000},
18722 {0x00008000, 0x80000000, 0x7fff0000, 0x00007fff},
18723 {0x19993bbb, 0xe800c800, 0x08880888, 0xf800f800},
18724 {0x44444444, 0xc000c000, 0xa0006666, 0x2222e000},
18726 static const DWORD content_q8w8v8u8[4][4] =
18728 {0x00000000, 0xff7f7f7f, 0x7f008880, 0x817f0000},
18729 {0x10000080, 0x20008000, 0x30007f00, 0x4000007f},
18730 {0x5020193b, 0x6028e8c8, 0x70020808, 0x807ff8f8},
18731 {0x90414444, 0xa000c0c0, 0x8261a066, 0x834922e0},
18733 static const DWORD content_x8l8v8u8[4][4] =
18735 {0x00000000, 0x00ff7f7f, 0x00008880, 0x00ff0000},
18736 {0x00000080, 0x00008000, 0x00007f00, 0x0000007f},
18737 {0x0041193b, 0x0051e8c8, 0x00040808, 0x00fff8f8},
18738 {0x00824444, 0x0000c0c0, 0x00c2a066, 0x009222e0},
18740 /* D3DFMT_L6V5U5 has poor precision on some GPUs. On a GeForce 7 the highest V and U value (15)
18741 * results in the output color 0xfb, which is 4 steps away from the correct value 0xff. It is
18742 * not the ~0xf0 you'd get if you blindly left-shifted the 5 bit value to form an 8 bit value
18743 * though.
18745 * There may also be an off-by-one bug involved: The value -7 should result in the output 0x47,
18746 * but ends up as 0x4d. Likewise, -3 becomes 0x6e instead of 0x67. Those values are close to
18747 * the proper results of -6 and -2.
18749 * On Wine the emulation with unsigned R5G6B5 has poor precision, e.g. the signed 0 becomes 16,
18750 * and ((16 / 31) - 0.5) * 2.0 is 0.032 instead of 0.000. The final output result we read back
18751 * is 0x84 instead of 0x80. */
18752 static const USHORT content_l6v5u5[4][4] =
18754 {0x0000, 0xfdef, 0x0230, 0xfc00},
18755 {0x0010, 0x0200, 0x01e0, 0x000f},
18756 {0x4067, 0x53b9, 0x0421, 0xffff},
18757 {0x8108, 0x0318, 0xc28c, 0x909c},
18759 static const struct
18761 D3DFORMAT format;
18762 const char *name;
18763 const void *content;
18764 SIZE_T pixel_size;
18765 BOOL blue, alpha;
18766 unsigned int slop, slop_broken, alpha_broken;
18768 formats[] =
18770 {D3DFMT_V8U8, "D3DFMT_V8U8", content_v8u8, sizeof(WORD), FALSE, FALSE, 1, 0, FALSE},
18771 {D3DFMT_V16U16, "D3DFMT_V16U16", content_v16u16, sizeof(DWORD), FALSE, FALSE, 1, 0, FALSE},
18772 {D3DFMT_Q8W8V8U8, "D3DFMT_Q8W8V8U8", content_q8w8v8u8, sizeof(DWORD), TRUE, TRUE, 1, 0, TRUE },
18773 {D3DFMT_X8L8V8U8, "D3DFMT_X8L8V8U8", content_x8l8v8u8, sizeof(DWORD), TRUE, FALSE, 1, 0, FALSE},
18774 {D3DFMT_L6V5U5, "D3DFMT_L6V5U5", content_l6v5u5, sizeof(WORD), TRUE, FALSE, 4, 7, FALSE},
18776 static const struct
18778 D3DPOOL pool;
18779 UINT width;
18780 RECT src_rect;
18781 POINT dst_point;
18783 tests[] =
18785 {D3DPOOL_SYSTEMMEM, 4, {1, 1, 2, 3}, {2, 0}},
18786 {D3DPOOL_SYSTEMMEM, 1, {0, 1, 1, 3}, {0, 0}},
18787 {D3DPOOL_MANAGED, 4, {1, 1, 2, 3}, {2, 0}},
18788 {D3DPOOL_MANAGED, 1, {0, 1, 1, 3}, {0, 0}},
18790 static const DWORD shader_code[] =
18792 0xffff0101, /* ps_1_1 */
18793 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0,5, 0,5 */
18794 0x00000042, 0xb00f0000, /* tex t0 */
18795 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
18796 0x0000ffff /* end */
18798 static const DWORD shader_code_alpha[] =
18800 /* The idea of this shader is to replicate the alpha value in .rg, and set
18801 * blue to 1.0 iff the alpha value is < -1.0 and 0.0 otherwise. */
18802 0xffff0101, /* ps_1_1 */
18803 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
18804 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
18805 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
18806 0x00000042, 0xb00f0000, /* tex t0 */
18807 0x00000004, 0x80070000, 0xb0ff0000, 0xa0e40000, 0xa0e40000, /* mad r0.rgb, t0.a, c0, c0 */
18808 0x00000003, 0x80080000, 0xb1ff0000, 0xa0e40000, /* sub r0.a, -t0.a, c0 */
18809 0x00000050, 0x80080000, 0x80ff0000, 0xa0ff0001, 0xa0ff0002, /* cnd r0.a, r0.a, c1.a, c2.a */
18810 0x00000005, 0x80070001, 0xa0e40001, 0x80e40000, /* mul r1.rgb, c1, r0 */
18811 0x00000004, 0x80070000, 0x80ff0000, 0xa0e40002, 0x80e40001, /* mad r0.rgb, r0.a, c2, r1 */
18812 0x0000ffff /* end */
18814 static const struct
18816 struct vec3 position;
18817 struct vec2 texcrd;
18819 quad[] =
18821 /* Flip the y coordinate to make the input and
18822 * output arrays easier to compare. */
18823 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 1.0f}},
18824 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 0.0f}},
18825 {{ 1.0f, -1.0f, 0.0f}, { 1.0f, 1.0f}},
18826 {{ 1.0f, 1.0f, 0.0f}, { 1.0f, 0.0f}},
18828 static const D3DCOLOR expected_alpha[4][4] =
18830 {0x00808000, 0x007f7f00, 0x00ffff00, 0x00000000},
18831 {0x00909000, 0x00a0a000, 0x00b0b000, 0x00c0c000},
18832 {0x00d0d000, 0x00e0e000, 0x00f0f000, 0x00000000},
18833 {0x00101000, 0x00202000, 0x00010100, 0x00020200},
18835 static const BOOL alpha_broken[4][4] =
18837 {FALSE, FALSE, FALSE, FALSE},
18838 {FALSE, FALSE, FALSE, FALSE},
18839 {FALSE, FALSE, FALSE, TRUE },
18840 {FALSE, FALSE, FALSE, FALSE},
18842 static const D3DCOLOR expected_colors[4][4] =
18844 {0x00808080, 0x00fefeff, 0x00010780, 0x008080ff},
18845 {0x00018080, 0x00800180, 0x0080fe80, 0x00fe8080},
18846 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
18847 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
18849 static const D3DCOLOR expected_colors2[4][4] =
18851 {0x00808080, 0x00fefeff, 0x00800180, 0x008080ff},
18852 {0x00018080, 0x00800180, 0x004767a8, 0x00fe8080},
18853 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
18854 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
18856 static const D3DCOLOR expected_colors3[4] =
18858 0x00018080,
18859 0x00ba98a0,
18860 0x00ba98a0,
18861 0x00c3c3c0,
18863 D3DCOLOR expected_color;
18865 window = create_window();
18866 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18867 ok(!!d3d, "Failed to create a D3D object.\n");
18869 if (!(device = create_device(d3d, window, window, TRUE)))
18871 skip("Failed to create a D3D device, skipping tests.\n");
18872 IDirect3D9_Release(d3d);
18873 DestroyWindow(window);
18874 return;
18877 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18878 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18880 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
18882 skip("Pixel shaders not supported, skipping converted format test.\n");
18883 goto done;
18886 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
18887 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18888 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
18889 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
18890 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
18891 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
18892 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_alpha, &shader_alpha);
18893 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
18895 for (i = 0; i < sizeof(formats) / sizeof(*formats); i++)
18897 hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
18898 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, formats[i].format);
18899 if (FAILED(hr))
18901 skip("Format %s not supported, skipping.\n", formats[i].name);
18902 continue;
18905 for (j = 0; j < sizeof(tests) / sizeof(*tests); j++)
18907 texture_sysmem = NULL;
18908 hr = IDirect3DDevice9_CreateTexture(device, tests[j].width, 4, 1, 0,
18909 formats[i].format, tests[j].pool, &texture, NULL);
18910 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
18912 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
18913 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
18914 for (y = 0; y < 4; y++)
18916 memcpy((char *)locked_rect.pBits + y * locked_rect.Pitch,
18917 (char *)formats[i].content + y * 4 * formats[i].pixel_size,
18918 tests[j].width * formats[i].pixel_size);
18920 hr = IDirect3DTexture9_UnlockRect(texture, 0);
18921 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
18923 if (tests[j].pool == D3DPOOL_SYSTEMMEM)
18925 texture_sysmem = texture;
18926 hr = IDirect3DDevice9_CreateTexture(device, tests[j].width, 4, 1, 0,
18927 formats[i].format, D3DPOOL_DEFAULT, &texture, NULL);
18928 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
18930 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture_sysmem,
18931 (IDirect3DBaseTexture9 *)texture);
18932 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
18935 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
18936 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
18937 hr = IDirect3DDevice9_SetPixelShader(device, shader_alpha);
18938 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18940 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
18941 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18942 hr = IDirect3DDevice9_BeginScene(device);
18943 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18944 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
18945 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18946 hr = IDirect3DDevice9_EndScene(device);
18947 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18949 for (y = 0; y < 4; y++)
18951 for (x = 0; x < tests[j].width; x++)
18953 BOOL r200_broken = formats[i].alpha_broken && alpha_broken[y][x];
18954 if (formats[i].alpha)
18955 expected_color = expected_alpha[y][x];
18956 else
18957 expected_color = 0x00ffff00;
18959 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
18960 ok(color_match(color, expected_color, 1) || broken(r200_broken),
18961 "Expected color 0x%08x, got 0x%08x, format %s, test %u, location %ux%u.\n",
18962 expected_color, color, formats[i].name, j, x, y);
18965 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18966 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18968 hr = IDirect3DDevice9_SetPixelShader(device, shader);
18969 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18971 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
18972 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18973 hr = IDirect3DDevice9_BeginScene(device);
18974 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18975 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
18976 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18977 hr = IDirect3DDevice9_EndScene(device);
18978 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18980 for (y = 0; y < 4; y++)
18982 for (x = 0; x < tests[j].width; x++)
18984 expected_color = expected_colors[y][x];
18985 if (!formats[i].blue)
18986 expected_color |= 0x000000ff;
18988 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
18989 ok(color_match(color, expected_color, formats[i].slop)
18990 || broken(color_match(color, expected_color, formats[i].slop_broken)),
18991 "Expected color 0x%08x, got 0x%08x, format %s, test %u, location %ux%u.\n",
18992 expected_color, color, formats[i].name, j, x, y);
18995 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18996 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18998 if (tests[j].pool != D3DPOOL_SYSTEMMEM)
19000 IDirect3DTexture9_Release(texture);
19001 continue;
19004 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &dst_surface);
19005 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x.\n", hr);
19006 IDirect3DTexture9_GetSurfaceLevel(texture_sysmem, 0, &src_surface);
19007 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x.\n", hr);
19009 hr = IDirect3DDevice9_UpdateSurface(device, src_surface,
19010 &tests[j].src_rect, dst_surface, &tests[j].dst_point);
19011 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
19013 IDirect3DSurface9_Release(dst_surface);
19014 IDirect3DSurface9_Release(src_surface);
19016 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00003300, 0.0f, 0);
19017 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19018 hr = IDirect3DDevice9_BeginScene(device);
19019 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19020 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
19021 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19022 hr = IDirect3DDevice9_EndScene(device);
19023 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19025 for (y = 0; y < 4; y++)
19027 for (x = 0; x < tests[j].width; x++)
19029 if (tests[j].width == 4)
19030 expected_color = expected_colors2[y][x];
19031 else
19032 expected_color = expected_colors3[y];
19034 if (!formats[i].blue)
19035 expected_color |= 0x000000ff;
19037 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
19038 ok(color_match(color, expected_color, formats[i].slop)
19039 || broken(color_match(color, expected_color, formats[i].slop_broken)),
19040 "Expected color 0x%08x, got 0x%08x, format %s, test %u, location %ux%u.\n",
19041 expected_color, color, formats[i].name, j, x, y);
19044 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19045 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19047 IDirect3DTexture9_Release(texture_sysmem);
19048 IDirect3DTexture9_Release(texture);
19052 IDirect3DPixelShader9_Release(shader);
19053 IDirect3DPixelShader9_Release(shader_alpha);
19055 done:
19056 refcount = IDirect3DDevice9_Release(device);
19057 ok(!refcount, "Device has %u references left.\n", refcount);
19058 IDirect3D9_Release(d3d);
19059 DestroyWindow(window);
19062 static void test_multisample_mismatch(void)
19064 IDirect3DDevice9 *device;
19065 IDirect3D9 *d3d;
19066 HWND window;
19067 HRESULT hr;
19068 D3DCOLOR color;
19069 ULONG refcount;
19070 IDirect3DSurface9 *rt, *rt_multi, *ds;
19071 static const struct
19073 struct vec3 position;
19074 DWORD color;
19076 quad[] =
19078 {{ -1.0f, -1.0f, 0.0f}, 0x000000ff},
19079 {{ -1.0f, 1.0f, 0.0f}, 0x000000ff},
19080 {{ 1.0f, -1.0f, 1.0f}, 0x000000ff},
19081 {{ 1.0f, 1.0f, 1.0f}, 0x000000ff},
19084 window = create_window();
19085 d3d = Direct3DCreate9(D3D_SDK_VERSION);
19086 ok(!!d3d, "Failed to create a D3D object.\n");
19087 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
19088 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
19090 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample mismatch test.\n");
19091 IDirect3D9_Release(d3d);
19092 return;
19094 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
19095 D3DFMT_D24X8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
19097 skip("Multisampling not supported for D3DFMT_D24X8, skipping multisample mismatch test.\n");
19098 IDirect3D9_Release(d3d);
19099 return;
19102 if (!(device = create_device(d3d, window, window, TRUE)))
19104 skip("Failed to create a D3D device, skipping tests.\n");
19105 IDirect3D9_Release(d3d);
19106 DestroyWindow(window);
19107 return;
19110 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
19111 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt_multi, NULL);
19112 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
19114 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.1f, 0);
19115 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19117 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
19118 ok(SUCCEEDED(hr), "Failed to set depth stencil, hr %#x.\n", hr);
19119 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
19120 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
19121 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
19122 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19124 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
19125 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19126 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
19127 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19129 /* Clear with incompatible buffers. Partial and combined clears. */
19130 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
19131 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19132 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.3f, 0);
19133 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19134 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 0.5f, 0);
19135 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19137 /* The color buffer is reliably cleared on AMD and Nvidia GPUs. */
19138 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
19139 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19140 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
19141 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
19142 color = getPixelColor(device, 320, 240);
19143 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
19144 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19145 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19147 /* Check depth buffer values. AMD GPUs (r500 and evergreen tested) clear the depth buffer
19148 * like you'd expect in a correct framebuffer setup. Nvidia doesn't clear it, neither in
19149 * the Z only clear case nor in the combined clear case. */
19150 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
19151 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
19152 hr = IDirect3DDevice9_BeginScene(device);
19153 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19154 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19155 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19156 hr = IDirect3DDevice9_EndScene(device);
19157 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19158 color = getPixelColor(device, 62, 240);
19159 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
19160 color = getPixelColor(device, 64, 240);
19161 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x000000ff, 1)),
19162 "Got unexpected color 0x%08x.\n", color);
19163 color = getPixelColor(device, 318, 240);
19164 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x000000ff, 1)),
19165 "Got unexpected color 0x%08x.\n", color);
19166 color = getPixelColor(device, 322, 240);
19167 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
19168 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19169 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19171 /* Draw with incompatible buffers. AMD even performs Z testing, and the Z test
19172 * results appear to be correct for this simple draw. Nvidia doesn't draw unless
19173 * the depth test is disabled. Setting ZFUNC = ALWAYS doesn't make the geometry
19174 * show up either. Only test the ZENABLE = FALSE case for now. */
19175 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
19176 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19177 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
19178 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19179 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
19180 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19181 hr = IDirect3DDevice9_BeginScene(device);
19182 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19183 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19184 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19185 hr = IDirect3DDevice9_EndScene(device);
19186 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19188 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
19189 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19190 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
19191 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
19192 color = getPixelColor(device, 320, 240);
19193 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
19194 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19195 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19197 IDirect3DSurface9_Release(ds);
19199 /* Test the reverse situation: Multisampled depth buffer, single sampled color buffer.
19200 * Color clears work as expected, AMD also clears the depth buffer, Nvidia does not. */
19201 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24X8,
19202 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
19203 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#x.\n", hr);
19204 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
19205 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
19206 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
19207 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19208 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ffff00, 0.1f, 0);
19209 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19211 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
19212 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19213 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
19214 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19215 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.3f, 0);
19216 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19217 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 0.5f, 0);
19218 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19220 color = getPixelColor(device, 320, 240);
19221 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
19222 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19223 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19225 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
19226 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19227 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
19228 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19229 hr = IDirect3DDevice9_BeginScene(device);
19230 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19231 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19232 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19233 hr = IDirect3DDevice9_EndScene(device);
19234 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19236 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
19237 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19238 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
19239 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
19240 color = getPixelColor(device, 62, 240);
19241 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
19242 color = getPixelColor(device, 318, 240);
19243 ok(color_match(color, 0x00ffff00, 1) || broken(color_match(color, 0x000000ff, 1)),
19244 "Got unexpected color 0x%08x.\n", color);
19245 color = getPixelColor(device, 322, 240);
19246 ok(color_match(color, 0x00ffff00, 1), "Got unexpected color 0x%08x.\n", color);
19247 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19248 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19250 /* Draw with a single sampled color buffer and a multisampled depth buffer. Again
19251 * AMD seems to perform correct Z testing, Nvidia doesn't draw unless the Z test
19252 * is disabled. Again only test the ZENABLE = FALSE case. */
19253 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
19254 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19255 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
19256 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19257 hr = IDirect3DDevice9_BeginScene(device);
19258 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19259 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19260 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19261 hr = IDirect3DDevice9_EndScene(device);
19262 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19263 color = getPixelColor(device, 320, 240);
19264 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
19265 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19266 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19268 IDirect3DSurface9_Release(rt);
19269 IDirect3DSurface9_Release(ds);
19270 IDirect3DSurface9_Release(rt_multi);
19272 refcount = IDirect3DDevice9_Release(device);
19273 ok(!refcount, "Device has %u references left.\n", refcount);
19274 IDirect3D9_Release(d3d);
19275 DestroyWindow(window);
19278 static void test_texcoordindex(void)
19280 static const D3DMATRIX mat =
19282 1.0f, 0.0f, 0.0f, 0.0f,
19283 0.0f, 0.0f, 0.0f, 0.0f,
19284 0.0f, 0.0f, 0.0f, 0.0f,
19285 0.0f, 0.0f, 0.0f, 0.0f,
19286 }}};
19287 static const struct
19289 struct vec3 pos;
19290 struct vec2 texcoord1;
19291 struct vec2 texcoord2;
19292 struct vec2 texcoord3;
19294 quad[] =
19296 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 1.0f}},
19297 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 0.0f}},
19298 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}, {1.0f, 0.0f}, {0.0f, 1.0f}},
19299 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 0.0f}},
19301 IDirect3DDevice9 *device;
19302 IDirect3D9 *d3d9;
19303 HWND window;
19304 HRESULT hr;
19305 IDirect3DTexture9 *texture1, *texture2;
19306 D3DLOCKED_RECT locked_rect;
19307 ULONG refcount;
19308 D3DCOLOR color;
19309 DWORD *ptr;
19311 window = create_window();
19312 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
19313 ok(!!d3d9, "Failed to create a D3D object.\n");
19314 if (!(device = create_device(d3d9, window, window, TRUE)))
19316 skip("Failed to create a D3D device, skipping tests.\n");
19317 IDirect3D9_Release(d3d9);
19318 DestroyWindow(window);
19319 return;
19322 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture1, NULL);
19323 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
19324 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
19325 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
19327 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
19328 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
19329 ptr = locked_rect.pBits;
19330 ptr[0] = 0xff000000;
19331 ptr[1] = 0xff00ff00;
19332 ptr[2] = 0xff0000ff;
19333 ptr[3] = 0xff00ffff;
19334 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
19335 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
19337 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
19338 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
19339 ptr = locked_rect.pBits;
19340 ptr[0] = 0xff000000;
19341 ptr[1] = 0xff0000ff;
19342 ptr[2] = 0xffff0000;
19343 ptr[3] = 0xffff00ff;
19344 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
19345 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
19347 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture1);
19348 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
19349 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *)texture2);
19350 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
19351 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX3);
19352 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
19353 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
19354 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
19355 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
19356 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
19357 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
19358 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
19359 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
19360 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
19361 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
19362 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
19363 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
19364 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
19365 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
19366 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
19368 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXCOORDINDEX, 1);
19369 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
19370 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 0);
19371 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
19373 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
19374 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19376 hr = IDirect3DDevice9_BeginScene(device);
19377 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19378 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19379 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19380 hr = IDirect3DDevice9_EndScene(device);
19381 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19383 color = getPixelColor(device, 160, 120);
19384 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
19385 color = getPixelColor(device, 480, 120);
19386 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19387 color = getPixelColor(device, 160, 360);
19388 ok(color_match(color, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color);
19389 color = getPixelColor(device, 480, 360);
19390 ok(color_match(color, 0x00ffffff, 2), "Got unexpected color 0x%08x.\n", color);
19392 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
19393 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
19394 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE1, &mat);
19395 ok(SUCCEEDED(hr), "Failed to set transformation matrix, hr %#x.\n", hr);
19397 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
19398 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19400 hr = IDirect3DDevice9_BeginScene(device);
19401 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19402 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19403 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19404 hr = IDirect3DDevice9_EndScene(device);
19405 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19407 color = getPixelColor(device, 160, 120);
19408 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
19409 color = getPixelColor(device, 480, 120);
19410 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19411 color = getPixelColor(device, 160, 360);
19412 ok(color_match(color, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color);
19413 color = getPixelColor(device, 480, 360);
19414 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19416 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
19417 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
19418 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 2);
19419 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
19421 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
19422 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19424 hr = IDirect3DDevice9_BeginScene(device);
19425 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19426 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19427 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19428 hr = IDirect3DDevice9_EndScene(device);
19429 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19431 color = getPixelColor(device, 160, 120);
19432 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
19433 color = getPixelColor(device, 480, 120);
19434 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19435 color = getPixelColor(device, 160, 360);
19436 ok(color_match(color, 0x00ff00ff, 2), "Got unexpected color 0x%08x.\n", color);
19437 color = getPixelColor(device, 480, 360);
19438 ok(color_match(color, 0x00ffff00, 2), "Got unexpected color 0x%08x.\n", color);
19440 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19441 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19443 IDirect3DTexture9_Release(texture1);
19444 IDirect3DTexture9_Release(texture2);
19446 refcount = IDirect3DDevice9_Release(device);
19447 ok(!refcount, "Device has %u references left.\n", refcount);
19448 IDirect3D9_Release(d3d9);
19449 DestroyWindow(window);
19452 static void test_vertex_blending(void)
19454 IDirect3DVertexDeclaration9 *vertex_declaration;
19455 IDirect3DDevice9 *device;
19456 IDirect3D9 *d3d;
19457 D3DCAPS9 caps;
19458 D3DCOLOR color;
19459 ULONG refcount;
19460 HWND window;
19461 HRESULT hr;
19462 int i;
19464 static const D3DMATRIX view_mat =
19466 2.0f / 10.0f, 0.0f, 0.0f, 0.0f,
19467 0.0f, 2.0f / 10.0f, 0.0f, 0.0f,
19468 0.0f, 0.0f, 1.0f, 0.0f,
19469 0.0f, 0.0f, 0.0f, 1.0f
19470 }}},
19471 upper_left =
19473 1.0f, 0.0f, 0.0f, 0.0f,
19474 0.0f, 1.0f, 0.0f, 0.0f,
19475 0.0f, 0.0f, 1.0f, 0.0f,
19476 -4.0f, 4.0f, 0.0f, 1.0f
19477 }}},
19478 lower_left =
19480 1.0f, 0.0f, 0.0f, 0.0f,
19481 0.0f, 1.0f, 0.0f, 0.0f,
19482 0.0f, 0.0f, 1.0f, 0.0f,
19483 -4.0f, -4.0f, 0.0f, 1.0f
19484 }}},
19485 upper_right =
19487 1.0f, 0.0f, 0.0f, 0.0f,
19488 0.0f, 1.0f, 0.0f, 0.0f,
19489 0.0f, 0.0f, 1.0f, 0.0f,
19490 4.0f, 4.0f, 0.0f, 1.0f
19491 }}},
19492 lower_right =
19494 1.0f, 0.0f, 0.0f, 0.0f,
19495 0.0f, 1.0f, 0.0f, 0.0f,
19496 0.0f, 0.0f, 1.0f, 0.0f,
19497 4.0f, -4.0f, 0.0f, 1.0f
19498 }}};
19500 static const POINT quad_upper_right_points[] =
19502 {576, 48}, {-1, -1},
19504 quad_upper_right_empty_points[] =
19506 {64, 48}, {64, 432}, {576, 432}, {320, 240}, {-1, -1}
19508 quad_center_points[] =
19510 {320, 240}, {-1, -1}
19512 quad_center_empty_points[] =
19514 {64, 48}, {576, 48}, {64, 432}, {576, 432}, {-1, -1}
19516 quad_upper_center_points[] =
19518 {320, 48}, {-1, -1}
19520 quad_upper_center_empty_points[] =
19522 {320, 240}, {64, 48}, {576, 48}, {-1, -1}
19524 quad_fullscreen_points[] =
19526 {320, 48}, {320, 240}, {64, 48}, {576, 48}, {64, 432}, {576, 432}, {-1, -1}
19528 quad_fullscreen_empty_points[] =
19530 {-1, -1}
19533 static const struct
19535 DWORD fvf;
19536 D3DVERTEXELEMENT9 decl_elements[3];
19537 struct
19539 struct
19541 struct vec3 position;
19542 struct vec3 blendweights;
19544 vertex_data_float[4];
19545 struct
19547 struct vec3 position;
19548 D3DCOLOR blendweights;
19550 vertex_data_d3dcolor[4];
19551 } s;
19552 const POINT *quad_points;
19553 const POINT *empty_points;
19555 tests[] =
19557 /* upper right */
19559 D3DFVF_XYZB3,
19560 {{0}},
19561 {{{{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
19562 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
19563 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
19564 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}}}},
19565 quad_upper_right_points, quad_upper_right_empty_points
19567 /* center */
19569 D3DFVF_XYZB3,
19570 {{0}},
19571 {{{{-1.0f, -1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}},
19572 {{-1.0f, 1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}},
19573 {{ 1.0f, -1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}},
19574 {{ 1.0f, 1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}}}},
19575 quad_center_points, quad_center_empty_points
19577 /* upper center */
19579 D3DFVF_XYZB3,
19580 {{0}},
19581 {{{{-1.0f, -1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}},
19582 {{-1.0f, 1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}},
19583 {{ 1.0f, -1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}},
19584 {{ 1.0f, 1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}}}},
19585 quad_upper_center_points, quad_upper_center_empty_points
19587 /* full screen */
19589 D3DFVF_XYZB3,
19590 {{0}},
19591 {{{{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}},
19592 {{-1.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}},
19593 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}},
19594 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}}}},
19595 quad_fullscreen_points, quad_fullscreen_empty_points
19597 /* D3DCOLOR, full screen */
19601 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
19602 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
19603 D3DDECL_END()
19605 {{{{0}}},
19606 {{{-1.0f, -1.0f, 0.0f}, 0x0000ff00},
19607 {{-1.0f, 1.0f, 0.0f}, 0x00ff0000},
19608 {{ 1.0f, -1.0f, 0.0f}, 0x000000ff},
19609 {{ 1.0f, 1.0f, 0.0f}, 0x00000000}}},
19610 quad_fullscreen_points, quad_fullscreen_empty_points
19614 window = create_window();
19615 d3d = Direct3DCreate9(D3D_SDK_VERSION);
19616 ok(!!d3d, "Failed to create a D3D object.\n");
19617 if (!(device = create_device(d3d, window, window, TRUE)))
19619 skip("Failed to create a D3D device, skipping tests.\n");
19620 goto done;
19623 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
19624 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
19625 if (caps.MaxVertexBlendMatrices < 4)
19627 skip("Only %u vertex blend matrices supported, skipping tests.\n", caps.MaxVertexBlendMatrices);
19628 IDirect3DDevice9_Release(device);
19629 goto done;
19632 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
19633 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
19635 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &view_mat);
19636 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19638 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &upper_left);
19639 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19640 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(1), &lower_left);
19641 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19642 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(2), &lower_right);
19643 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19644 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(3), &upper_right);
19645 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19647 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_VERTEXBLEND, D3DVBF_3WEIGHTS);
19648 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed %08x\n", hr);
19650 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
19652 const POINT *point;
19654 if (tests[i].fvf)
19656 hr = IDirect3DDevice9_SetFVF(device, tests[i].fvf);
19657 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
19658 vertex_declaration = NULL;
19660 else
19662 hr = IDirect3DDevice9_CreateVertexDeclaration(device, tests[i].decl_elements, &vertex_declaration);
19663 ok(SUCCEEDED(hr), "Failed to create vertex declaration, hr %#x.\n", hr);
19664 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
19665 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
19668 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
19669 ok(SUCCEEDED(hr), "Failed to clear %08x\n", hr);
19671 hr = IDirect3DDevice9_BeginScene(device);
19672 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19674 if (tests[i].fvf)
19675 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
19676 tests[i].s.vertex_data_float, sizeof(*tests[i].s.vertex_data_float));
19677 else
19678 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
19679 tests[i].s.vertex_data_d3dcolor, sizeof(*tests[i].s.vertex_data_d3dcolor));
19680 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19682 hr = IDirect3DDevice9_EndScene(device);
19683 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19685 point = tests[i].quad_points;
19686 while (point->x != -1 && point->y != -1)
19688 color = getPixelColor(device, point->x, point->y);
19689 ok(color_match(color, 0x00ffffff, 1), "Expected quad at %dx%d.\n", point->x, point->y);
19690 ++point;
19693 point = tests[i].empty_points;
19694 while (point->x != -1 && point->y != -1)
19696 color = getPixelColor(device, point->x, point->y);
19697 ok(color_match(color, 0x00000000, 1), "Unexpected quad at %dx%d.\n", point->x, point->y);
19698 ++point;
19701 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19702 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19704 if (vertex_declaration)
19705 IDirect3DVertexDeclaration9_Release(vertex_declaration);
19708 refcount = IDirect3DDevice9_Release(device);
19709 ok(!refcount, "Device has %u references left.\n", refcount);
19711 done:
19712 IDirect3D9_Release(d3d);
19713 DestroyWindow(window);
19716 static void test_updatetexture(void)
19718 BOOL r32f_supported, ati2n_supported, do_visual_test;
19719 IDirect3DBaseTexture9 *src, *dst;
19720 unsigned int t, i, f, l, x, y, z;
19721 D3DLOCKED_RECT locked_rect;
19722 D3DLOCKED_BOX locked_box;
19723 IDirect3DDevice9 *device;
19724 IDirect3D9 *d3d9;
19725 ULONG refcount;
19726 D3DCOLOR color;
19727 D3DCAPS9 caps;
19728 HWND window;
19729 HRESULT hr;
19730 static const struct
19732 struct vec3 pos;
19733 struct vec2 texcoord;
19735 quad[] =
19737 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}},
19738 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}},
19739 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}},
19740 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
19742 static const struct
19744 struct vec3 pos;
19745 struct vec3 texcoord;
19747 quad_cube_tex[] =
19749 {{-1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, 0.5f}},
19750 {{-1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, 0.5f}},
19751 {{ 1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, -0.5f}},
19752 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, -0.5f}},
19754 static const struct
19756 UINT src_width, src_height;
19757 UINT dst_width, dst_height;
19758 UINT src_levels, dst_levels;
19759 D3DFORMAT src_format, dst_format;
19760 BOOL broken;
19762 tests[] =
19764 {8, 8, 8, 8, 0, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 0 */
19765 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 1 */
19766 {8, 8, 8, 8, 2, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 2 */
19767 {8, 8, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 3 */
19768 {8, 8, 8, 8, 4, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 4 */
19769 {8, 8, 2, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 5 */
19770 /* The WARP renderer doesn't handle these cases correctly. */
19771 {8, 8, 8, 8, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 6 */
19772 {8, 8, 4, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 7 */
19773 /* Not clear what happens here on Windows, it doesn't make much sense
19774 * though (on Nvidia it seems to upload the 4x4 surface into the 7x7
19775 * one or something like that). */
19776 /* {8, 8, 7, 7, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
19777 {8, 8, 8, 8, 1, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 8 */
19778 {4, 4, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 9 */
19779 /* This one causes weird behavior on Windows (it probably writes out
19780 * of the texture memory). */
19781 /* {8, 8, 4, 4, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
19782 {8, 4, 4, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 10 */
19783 {8, 4, 2, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 11 */
19784 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8, FALSE}, /* 12 */
19785 {8, 8, 8, 8, 4, 4, D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 13 */
19786 /* The data is converted correctly on AMD, on Nvidia nothing happens
19787 * (it draws a black quad). */
19788 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_R5G6B5, TRUE}, /* 14 */
19789 /* Here the data is converted on AMD, just copied and "reinterpreted" as
19790 * a 32 bit float on Nvidia (specifically the tested value becomes a
19791 * very small float number which we get as 0 in the test). */
19792 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_R32F, TRUE}, /* 15 */
19793 /* This one doesn't seem to give the expected results on AMD. */
19794 /* {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_Q8W8V8U8, FALSE}, */
19795 {8, 8, 8, 8, 4, 4, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 16 */
19796 {8, 8, 8, 8, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 17 */
19797 {8, 8, 2, 2, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 18 */
19799 static const struct
19801 D3DRESOURCETYPE type;
19802 DWORD fvf;
19803 const void *quad;
19804 unsigned int vertex_size;
19805 DWORD cap;
19806 const char *name;
19808 texture_types[] =
19810 {D3DRTYPE_TEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
19811 quad, sizeof(*quad), D3DPTEXTURECAPS_MIPMAP, "2D mipmapped"},
19813 {D3DRTYPE_CUBETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0),
19814 quad_cube_tex, sizeof(*quad_cube_tex), D3DPTEXTURECAPS_CUBEMAP, "Cube"},
19816 {D3DRTYPE_VOLUMETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
19817 quad, sizeof(*quad), D3DPTEXTURECAPS_VOLUMEMAP, "Volume"}
19820 window = create_window();
19821 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
19822 ok(!!d3d9, "Failed to create a D3D object.\n");
19823 if (!(device = create_device(d3d9, window, window, TRUE)))
19825 skip("Failed to create a D3D device, skipping tests.\n");
19826 IDirect3D9_Release(d3d9);
19827 DestroyWindow(window);
19828 return;
19831 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
19832 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
19834 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
19835 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#x.\n", hr);
19836 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
19837 ok(SUCCEEDED(hr), "Failed to set texture clamping state, hr %#x.\n", hr);
19838 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
19839 ok(SUCCEEDED(hr), "Failed to set texture clamping state, hr %#x.\n", hr);
19840 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
19841 ok(SUCCEEDED(hr), "Failed to set texture clamping state, hr %#x.\n", hr);
19842 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
19843 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19844 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
19845 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#x.\n", hr);
19846 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
19847 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#x.\n", hr);
19849 for (t = 0; t < sizeof(texture_types) / sizeof(*texture_types); ++t)
19851 if (!(caps.TextureCaps & texture_types[t].cap))
19853 skip("%s textures not supported, skipping some tests.\n", texture_types[t].name);
19854 continue;
19856 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
19857 D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_FILTER, texture_types[t].type, D3DFMT_A8R8G8B8)))
19859 skip("%s D3DFMT_A8R8G8B8 texture filtering is not supported, skipping some tests.\n",
19860 texture_types[t].name);
19861 continue;
19863 r32f_supported = TRUE;
19864 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
19865 D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_FILTER, texture_types[t].type, D3DFMT_R32F)))
19867 skip("%s R32F textures are not supported, skipping some tests.\n", texture_types[t].name);
19868 r32f_supported = FALSE;
19870 ati2n_supported = TRUE;
19871 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
19872 D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_FILTER, texture_types[t].type, MAKEFOURCC('A','T','I','2'))))
19874 skip("%s ATI2N textures are not supported, skipping some tests.\n", texture_types[t].name);
19875 ati2n_supported = FALSE;
19878 hr = IDirect3DDevice9_SetFVF(device, texture_types[t].fvf);
19879 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
19881 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
19883 if (tests[i].dst_format == D3DFMT_R32F && !r32f_supported)
19884 continue;
19885 if (tests[i].dst_format == MAKEFOURCC('A','T','I','2') && !ati2n_supported)
19886 continue;
19888 switch (texture_types[t].type)
19890 case D3DRTYPE_TEXTURE:
19891 hr = IDirect3DDevice9_CreateTexture(device,
19892 tests[i].src_width, tests[i].src_height,
19893 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
19894 (IDirect3DTexture9 **)&src, NULL);
19895 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19896 hr = IDirect3DDevice9_CreateTexture(device,
19897 tests[i].dst_width, tests[i].dst_height,
19898 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
19899 (IDirect3DTexture9 **)&dst, NULL);
19900 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19901 break;
19902 case D3DRTYPE_CUBETEXTURE:
19903 hr = IDirect3DDevice9_CreateCubeTexture(device,
19904 tests[i].src_width,
19905 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
19906 (IDirect3DCubeTexture9 **)&src, NULL);
19907 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19908 hr = IDirect3DDevice9_CreateCubeTexture(device,
19909 tests[i].dst_width,
19910 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
19911 (IDirect3DCubeTexture9 **)&dst, NULL);
19912 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19913 break;
19914 case D3DRTYPE_VOLUMETEXTURE:
19915 hr = IDirect3DDevice9_CreateVolumeTexture(device,
19916 tests[i].src_width, tests[i].src_height, tests[i].src_width,
19917 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
19918 (IDirect3DVolumeTexture9 **)&src, NULL);
19919 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19920 hr = IDirect3DDevice9_CreateVolumeTexture(device,
19921 tests[i].dst_width, tests[i].dst_height, tests[i].dst_width,
19922 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
19923 (IDirect3DVolumeTexture9 **)&dst, NULL);
19924 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19925 break;
19926 default:
19927 trace("Unexpected resource type.\n");
19930 /* Skip the visual part of the test for ATI2N (laziness) and cases that
19931 * give a different (and unlikely to be useful) result. */
19932 do_visual_test = (tests[i].src_format == D3DFMT_A8R8G8B8 || tests[i].src_format == D3DFMT_X8R8G8B8)
19933 && tests[i].src_levels != 0
19934 && tests[i].src_width >= tests[i].dst_width && tests[i].src_height >= tests[i].dst_height
19935 && !(tests[i].src_width > tests[i].src_height && tests[i].dst_width < tests[i].dst_height);
19937 if (do_visual_test)
19939 DWORD *ptr = NULL;
19940 unsigned int width, height, depth, row_pitch = 0, slice_pitch = 0;
19942 for (f = 0; f < (texture_types[t].type == D3DRTYPE_CUBETEXTURE ? 6 : 1); ++f)
19944 width = tests[i].src_width;
19945 height = texture_types[t].type != D3DRTYPE_CUBETEXTURE ? tests[i].src_height : tests[i].src_width;
19946 depth = texture_types[t].type == D3DRTYPE_VOLUMETEXTURE ? width : 1;
19948 for (l = 0; l < tests[i].src_levels; ++l)
19950 switch (texture_types[t].type)
19952 case D3DRTYPE_TEXTURE:
19953 hr = IDirect3DTexture9_LockRect((IDirect3DTexture9 *)src,
19954 l, &locked_rect, NULL, 0);
19955 ptr = locked_rect.pBits;
19956 row_pitch = locked_rect.Pitch / sizeof(*ptr);
19957 break;
19958 case D3DRTYPE_CUBETEXTURE:
19959 hr = IDirect3DCubeTexture9_LockRect((IDirect3DCubeTexture9 *)src,
19960 f, l, &locked_rect, NULL, 0);
19961 ptr = locked_rect.pBits;
19962 row_pitch = locked_rect.Pitch / sizeof(*ptr);
19963 break;
19964 case D3DRTYPE_VOLUMETEXTURE:
19965 hr = IDirect3DVolumeTexture9_LockBox((IDirect3DVolumeTexture9 *)src,
19966 l, &locked_box, NULL, 0);
19967 ptr = locked_box.pBits;
19968 row_pitch = locked_box.RowPitch / sizeof(*ptr);
19969 slice_pitch = locked_box.SlicePitch / sizeof(*ptr);
19970 break;
19971 default:
19972 trace("Unexpected resource type.\n");
19974 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
19976 for (z = 0; z < depth; ++z)
19978 for (y = 0; y < height; ++y)
19980 for (x = 0; x < width; ++x)
19982 ptr[z * slice_pitch + y * row_pitch + x] = 0xff000000
19983 | (DWORD)(x / (width - 1.0f) * 255.0f) << 16
19984 | (DWORD)(y / (height - 1.0f) * 255.0f) << 8;
19989 switch (texture_types[t].type)
19991 case D3DRTYPE_TEXTURE:
19992 hr = IDirect3DTexture9_UnlockRect((IDirect3DTexture9 *)src, l);
19993 break;
19994 case D3DRTYPE_CUBETEXTURE:
19995 hr = IDirect3DCubeTexture9_UnlockRect((IDirect3DCubeTexture9 *)src, f, l);
19996 break;
19997 case D3DRTYPE_VOLUMETEXTURE:
19998 hr = IDirect3DVolumeTexture9_UnlockBox((IDirect3DVolumeTexture9 *)src, l);
19999 break;
20000 default:
20001 trace("Unexpected resource type.\n");
20003 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
20005 width >>= 1;
20006 if (!width)
20007 width = 1;
20008 height >>= 1;
20009 if (!height)
20010 height = 1;
20011 depth >>= 1;
20012 if (!depth)
20013 depth = 1;
20018 hr = IDirect3DDevice9_UpdateTexture(device, src, dst);
20019 if (FAILED(hr))
20021 todo_wine ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u, %u.\n", hr, t, i);
20022 IDirect3DBaseTexture9_Release(src);
20023 IDirect3DBaseTexture9_Release(dst);
20024 continue;
20026 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u, %u.\n", hr, t, i);
20028 if (do_visual_test)
20030 hr = IDirect3DDevice9_SetTexture(device, 0, dst);
20031 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
20033 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 1.0f, 0);
20034 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
20036 hr = IDirect3DDevice9_BeginScene(device);
20037 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
20038 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
20039 texture_types[t].quad, texture_types[t].vertex_size);
20040 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20041 hr = IDirect3DDevice9_EndScene(device);
20042 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
20044 color = getPixelColor(device, 320, 240);
20045 ok (color_match(color, 0x007f7f00, 3) || broken(tests[i].broken)
20046 || broken(color == 0x00adbeef), /* WARP device often just breaks down. */
20047 "Got unexpected color 0x%08x, case %u, %u.\n", color, t, i);
20050 IDirect3DBaseTexture9_Release(src);
20051 IDirect3DBaseTexture9_Release(dst);
20054 refcount = IDirect3DDevice9_Release(device);
20055 ok(!refcount, "Device has %u references left.\n", refcount);
20056 IDirect3D9_Release(d3d9);
20057 DestroyWindow(window);
20060 static void test_depthbias(void)
20062 IDirect3DDevice9 *device;
20063 IDirect3D9 *d3d;
20064 IDirect3DSurface9 *ds;
20065 D3DCAPS9 caps;
20066 D3DCOLOR color;
20067 ULONG refcount;
20068 HWND window;
20069 HRESULT hr;
20070 unsigned int i;
20071 static const D3DFORMAT formats[] =
20073 D3DFMT_D16, D3DFMT_D24X8, D3DFMT_D32, D3DFMT_D24S8, MAKEFOURCC('I','N','T','Z'),
20075 /* The scaling factor detection function detects the wrong factor for
20076 * float formats on Nvidia, therefore the following tests are disabled.
20077 * The wined3d function detects 2^23 like for fixed point formats but
20078 * the test needs 2^22 to pass.
20080 * AMD GPUs need a different scaling factor for float depth buffers
20081 * (2^24) than fixed point (2^23), but the wined3d detection function
20082 * works there, producing the right result in the test.
20084 * D3DFMT_D32F_LOCKABLE, D3DFMT_D24FS8,
20088 static const struct
20090 struct vec3 position;
20092 quad[] =
20094 {{-1.0f, -1.0f, 0.0f}},
20095 {{-1.0f, 1.0f, 0.0f}},
20096 {{ 1.0f, -1.0f, 1.0f}},
20097 {{ 1.0f, 1.0f, 1.0f}},
20099 union
20101 float f;
20102 DWORD d;
20103 } conv;
20105 window = create_window();
20106 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20107 ok(!!d3d, "Failed to create a D3D object.\n");
20108 if (!(device = create_device(d3d, window, window, TRUE)))
20110 skip("Failed to create a D3D device, skipping tests.\n");
20111 goto done;
20114 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
20115 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
20116 if (!(caps.RasterCaps & D3DPRASTERCAPS_DEPTHBIAS))
20118 IDirect3DDevice9_Release(device);
20119 skip("D3DPRASTERCAPS_DEPTHBIAS not supported.\n");
20120 goto done;
20123 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
20124 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
20125 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
20126 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
20127 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
20128 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
20129 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
20130 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
20131 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
20132 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
20134 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
20136 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20137 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, formats[i])))
20139 skip("Depth format %u not supported, skipping.\n", formats[i]);
20140 continue;
20143 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, formats[i],
20144 D3DMULTISAMPLE_NONE, 0, FALSE, &ds, NULL);
20145 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
20146 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
20147 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
20148 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 0.5f, 0);
20149 ok(SUCCEEDED(hr), "Failed to clear %08x\n", hr);
20151 hr = IDirect3DDevice9_BeginScene(device);
20152 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
20154 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x00ff0000);
20155 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20156 conv.f = -0.2f;
20157 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
20158 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20159 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20160 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20162 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
20163 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20164 conv.f = 0.0f;
20165 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
20166 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20167 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20168 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20170 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x000000ff);
20171 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20172 conv.f = 0.2f;
20173 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
20174 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20175 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20176 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20178 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x00ffffff);
20179 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20180 conv.f = 0.4f;
20181 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
20182 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20183 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20184 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20186 color = getPixelColor(device, 61, 240);
20187 ok(color_match(color, 0x00ffffff, 1), "Got unexpected color %08x at x=62, format %u.\n", color, formats[i]);
20188 color = getPixelColor(device, 65, 240);
20190 /* The broken results are for the WARP driver on the testbot. It seems to initialize
20191 * a scaling factor based on the first depth format that is used. Other formats with
20192 * a different depth size then render incorrectly. */
20193 ok(color_match(color, 0x000000ff, 1) || broken(color_match(color, 0x00ffffff, 1)),
20194 "Got unexpected color %08x at x=64, format %u.\n", color, formats[i]);
20195 color = getPixelColor(device, 190, 240);
20196 ok(color_match(color, 0x000000ff, 1) || broken(color_match(color, 0x00ffffff, 1)),
20197 "Got unexpected color %08x at x=190, format %u.\n", color, formats[i]);
20199 color = getPixelColor(device, 194, 240);
20200 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ffffff, 1)),
20201 "Got unexpected color %08x at x=194, format %u.\n", color, formats[i]);
20202 color = getPixelColor(device, 318, 240);
20203 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ffffff, 1)),
20204 "Got unexpected color %08x at x=318, format %u.\n", color, formats[i]);
20206 color = getPixelColor(device, 322, 240);
20207 ok(color_match(color, 0x00ff0000, 1) || broken(color_match(color, 0x00000000, 1)),
20208 "Got unexpected color %08x at x=322, format %u.\n", color, formats[i]);
20209 color = getPixelColor(device, 446, 240);
20210 ok(color_match(color, 0x00ff0000, 1) || broken(color_match(color, 0x00000000, 1)),
20211 "Got unexpected color %08x at x=446, format %u.\n", color, formats[i]);
20213 color = getPixelColor(device, 450, 240);
20214 ok(color_match(color, 0x00000000, 1), "Got unexpected color %08x at x=446, format %u.\n", color, formats[i]);
20216 hr = IDirect3DDevice9_EndScene(device);
20217 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
20219 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20220 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
20221 IDirect3DSurface9_Release(ds);
20224 refcount = IDirect3DDevice9_Release(device);
20225 ok(!refcount, "Device has %u references left.\n", refcount);
20227 done:
20228 IDirect3D9_Release(d3d);
20229 DestroyWindow(window);
20232 static void test_flip(void)
20234 IDirect3DDevice9 *device;
20235 IDirect3D9 *d3d;
20236 ULONG refcount;
20237 HWND window;
20238 HRESULT hr;
20239 IDirect3DSurface9 *back_buffers[3], *test_surface;
20240 unsigned int i;
20241 D3DCOLOR color;
20242 D3DPRESENT_PARAMETERS present_parameters = {0};
20244 window = create_window();
20245 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20246 ok(!!d3d, "Failed to create a D3D object.\n");
20248 present_parameters.BackBufferWidth = 640;
20249 present_parameters.BackBufferHeight = 480;
20250 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
20251 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
20252 present_parameters.hDeviceWindow = window;
20253 present_parameters.Windowed = TRUE;
20254 present_parameters.BackBufferCount = 3;
20255 present_parameters.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
20256 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20257 window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
20258 if (!device)
20260 skip("Failed to create a D3D device, skipping tests.\n");
20261 IDirect3D9_Release(d3d);
20262 DestroyWindow(window);
20263 return;
20266 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
20268 hr = IDirect3DDevice9_GetBackBuffer(device, 0, i, D3DBACKBUFFER_TYPE_MONO, &back_buffers[i]);
20269 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
20271 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &test_surface);
20272 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
20273 ok(test_surface == back_buffers[0], "Expected render target %p, got %p.\n", back_buffers[0], test_surface);
20274 IDirect3DSurface9_Release(test_surface);
20276 hr = IDirect3DDevice9_SetRenderTarget(device, 0, back_buffers[2]);
20277 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
20279 hr = IDirect3DDevice9_ColorFill(device, back_buffers[0], NULL, 0xffff0000);
20280 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x.\n", hr);
20281 hr = IDirect3DDevice9_ColorFill(device, back_buffers[1], NULL, 0xff00ff00);
20282 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x.\n", hr);
20283 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
20284 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
20286 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20287 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20289 /* Render target is unmodified. */
20290 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &test_surface);
20291 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
20292 ok(test_surface == back_buffers[2], "Expected render target %p, got %p.\n", back_buffers[2], test_surface);
20293 IDirect3DSurface9_Release(test_surface);
20295 /* Backbuffer surface pointers are unmodified */
20296 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
20298 hr = IDirect3DDevice9_GetBackBuffer(device, 0, i, D3DBACKBUFFER_TYPE_MONO, &test_surface);
20299 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
20300 ok(test_surface == back_buffers[i], "Expected back buffer %u = %p, got %p.\n",
20301 i, back_buffers[i], test_surface);
20302 IDirect3DSurface9_Release(test_surface);
20305 /* Contents were changed. */
20306 color = getPixelColorFromSurface(back_buffers[0], 1, 1);
20307 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
20308 color = getPixelColorFromSurface(back_buffers[1], 1, 1);
20309 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
20311 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0f, 0);
20312 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
20314 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20315 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20317 color = getPixelColorFromSurface(back_buffers[0], 1, 1);
20318 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
20319 color = getPixelColorFromSurface(back_buffers[1], 1, 1);
20320 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
20322 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20323 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20325 color = getPixelColorFromSurface(back_buffers[0], 1, 1);
20326 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
20328 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
20329 IDirect3DSurface9_Release(back_buffers[i]);
20331 refcount = IDirect3DDevice9_Release(device);
20332 ok(!refcount, "Device has %u references left.\n", refcount);
20334 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20335 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
20337 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample flip test.\n");
20338 goto done;
20341 present_parameters.BackBufferCount = 2;
20342 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
20343 present_parameters.Flags = 0;
20344 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20345 window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
20347 for (i = 0; i < present_parameters.BackBufferCount; ++i)
20349 hr = IDirect3DDevice9_GetBackBuffer(device, 0, i, D3DBACKBUFFER_TYPE_MONO, &back_buffers[i]);
20350 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
20353 hr = IDirect3DDevice9_SetRenderTarget(device, 0, back_buffers[1]);
20354 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
20355 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0f, 0);
20356 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
20358 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20359 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20361 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
20362 D3DMULTISAMPLE_NONE, 0, TRUE, &test_surface, NULL);
20363 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
20364 hr = IDirect3DDevice9_StretchRect(device, back_buffers[0], NULL, test_surface, NULL, D3DTEXF_POINT);
20365 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
20367 color = getPixelColorFromSurface(test_surface, 1, 1);
20368 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
20370 IDirect3DSurface9_Release(test_surface);
20371 for (i = 0; i < present_parameters.BackBufferCount; ++i)
20372 IDirect3DSurface9_Release(back_buffers[i]);
20374 refcount = IDirect3DDevice9_Release(device);
20375 ok(!refcount, "Device has %u references left.\n", refcount);
20377 done:
20378 IDirect3D9_Release(d3d);
20379 DestroyWindow(window);
20382 static void test_uninitialized_varyings(void)
20384 static const D3DMATRIX mat =
20386 1.0f, 0.0f, 0.0f, 0.0f,
20387 0.0f, 1.0f, 0.0f, 0.0f,
20388 0.0f, 0.0f, 1.0f, 0.0f,
20389 0.0f, 0.0f, 0.0f, 1.0f,
20390 }}};
20391 static const struct vec3 quad[] =
20393 {-1.0f, -1.0f, 0.1f},
20394 {-1.0f, 1.0f, 0.1f},
20395 { 1.0f, -1.0f, 0.1f},
20396 { 1.0f, 1.0f, 0.1f},
20398 static const DWORD vs1_code[] =
20400 0xfffe0101, /* vs_1_1 */
20401 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20402 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
20403 0x0000ffff
20405 static const DWORD vs1_partial_code[] =
20407 0xfffe0101, /* vs_1_1 */
20408 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20409 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
20410 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
20411 0x00000001, 0xd0010000, 0xa0e40000, /* mov oD0.x, c0 */
20412 0x00000001, 0xd0010001, 0xa0e40000, /* mov oD1.x, c0 */
20413 0x00000001, 0xe0010000, 0xa0e40000, /* mov oT0.x, c0 */
20414 0x0000ffff
20416 static const DWORD vs2_code[] =
20418 0xfffe0200, /* vs_2_0 */
20419 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20420 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
20421 0x0000ffff
20423 static const DWORD vs2_partial_code[] =
20425 0xfffe0200, /* vs_2_0 */
20426 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20427 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
20428 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
20429 0x02000001, 0xd0010000, 0xa0e40000, /* mov oD0.x, c0 */
20430 0x02000001, 0xd0010001, 0xa0e40000, /* mov oD1.x, c0 */
20431 0x02000001, 0xe0010000, 0xa0e40000, /* mov oT0.x, c0 */
20432 0x0000ffff
20434 static const DWORD vs3_code[] =
20436 0xfffe0300, /* vs_3_0 */
20437 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20438 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
20439 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
20440 0x0000ffff
20442 static const DWORD vs3_partial_code[] =
20444 0xfffe0300, /* vs_3_0 */
20445 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20446 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
20447 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
20448 0x0200001f, 0x8001000a, 0xe00f0002, /* dcl_color1 o2 */
20449 0x0200001f, 0x80000005, 0xe00f0003, /* dcl_texcoord0 o3 */
20450 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
20451 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
20452 0x02000001, 0xe0010001, 0xa0e40000, /* mov o1.x, c0 */
20453 0x02000001, 0xe0010002, 0xa0e40000, /* mov o2.x, c0 */
20454 0x02000001, 0xe0010003, 0xa0e40000, /* mov o3.x, c0 */
20455 0x0000ffff
20457 static const DWORD ps1_diffuse_code[] =
20459 0xffff0101, /* ps_1_1 */
20460 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
20461 0x0000ffff
20463 static const DWORD ps1_specular_code[] =
20465 0xffff0101, /* ps_1_1 */
20466 0x00000001, 0x800f0000, 0x90e40001, /* mov r0, v1 */
20467 0x0000ffff
20469 static const DWORD ps1_texcoord_code[] =
20471 0xffff0101, /* ps_1_1 */
20472 0x00000040, 0xb00f0000, /* texcoord t0 */
20473 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
20474 0x0000ffff
20476 static const DWORD ps2_diffuse_code[] =
20478 0xffff0200, /* ps_2_0 */
20479 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
20480 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
20481 0x0000ffff
20483 static const DWORD ps2_specular_code[] =
20485 0xffff0200, /* ps_2_0 */
20486 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
20487 0x02000001, 0x800f0800, 0x90e40001, /* mov oC0, v1 */
20488 0x0000ffff
20490 static const DWORD ps2_texcoord_code[] =
20492 0xffff0200, /* ps_2_0 */
20493 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
20494 0x02000001, 0x800f0800, 0xb0e40000, /* mov oC0, t0 */
20495 0x0000ffff
20497 #if 0
20498 /* This has been left here for documentation purposes. It is referenced in disabled tests in the table below. */
20499 static const DWORD ps3_diffuse_code[] =
20501 0xffff0300, /* ps_3_0 */
20502 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
20503 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
20504 0x0000ffff
20506 #endif
20507 static const DWORD ps3_specular_code[] =
20509 0xffff0300, /* ps_3_0 */
20510 0x0200001f, 0x8001000a, 0x900f0001, /* dcl_color1 v1 */
20511 0x02000001, 0x800f0800, 0x90e40001, /* mov oC0, v1 */
20512 0x0000ffff
20514 static const DWORD ps3_texcoord_code[] =
20516 0xffff0300, /* ps_3_0 */
20517 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
20518 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
20519 0x0000ffff
20521 static const struct
20523 DWORD vs_version;
20524 const DWORD *vs;
20525 DWORD ps_version;
20526 const DWORD *ps;
20527 D3DCOLOR expected;
20528 BOOL allow_zero_alpha;
20529 BOOL partial;
20530 BOOL broken_warp;
20532 /* On AMD specular color is generally initialized to 0x00000000 and texcoords to 0xff000000
20533 * while on Nvidia it's the opposite. Just allow both.
20535 * Partially initialized varyings reliably handle the component that has been initialized.
20536 * The uninitialized components generally follow the rule above, with some exceptions on
20537 * radeon cards. r500 and r600 GPUs have been found to set uninitialized components to 0.0,
20538 * 0.5 and 1.0 without a sensible pattern. */
20539 tests[] =
20541 {D3DVS_VERSION(1, 1), vs1_code, 0, NULL, 0xffffffff},
20542 { 0, NULL, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff000000, TRUE},
20543 { 0, NULL, D3DPS_VERSION(2, 0), ps2_texcoord_code, 0xff000000, TRUE},
20544 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_diffuse_code, 0xffffffff},
20545 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_specular_code, 0xff000000, TRUE, FALSE, TRUE},
20546 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff000000, TRUE},
20547 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_diffuse_code, 0xffffffff},
20548 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_specular_code, 0xff000000, TRUE, FALSE, TRUE},
20549 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_texcoord_code, 0xff000000, TRUE},
20550 /* This test shows a lot of combinations of alpha and color that involve 1.0 and 0.0. Disable it.
20552 * AMD r500 sets alpha = 1.0, color = 0.0. Nvidia sets alpha = 1.0, color = 1.0. r600 Sets Alpha = 0.0,
20553 * color = 0.0. So far no combination with Alpha = 0.0, color = 1.0 has been found though.
20554 * {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_diffuse_code, 0xffffffff, FALSE, FALSE},
20556 * The same issues apply to the partially initialized COLOR0 varying, in addition to unreliable results
20557 * with partially initialized varyings in general.
20558 * {D3DVS_VERSION(3, 0), vs3_partial_code, D3DPS_VERSION(3, 0), ps3_diffuse_code, 0xff7fffff, TRUE, TRUE}, */
20559 {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_specular_code, 0xff000000, TRUE, FALSE, TRUE},
20560 {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_texcoord_code, 0xff000000, TRUE, FALSE, TRUE},
20561 {D3DVS_VERSION(1, 1), vs1_partial_code, 0, NULL, 0xff7fffff, FALSE, TRUE},
20562 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_diffuse_code, 0xff7fffff, FALSE, TRUE},
20563 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_specular_code, 0xff7f0000, TRUE, TRUE},
20564 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff7f0000, TRUE, TRUE},
20565 {D3DVS_VERSION(2, 0), vs2_partial_code, D3DPS_VERSION(2, 0), ps2_diffuse_code, 0xff7fffff, FALSE, TRUE},
20566 {D3DVS_VERSION(2, 0), vs2_partial_code, D3DPS_VERSION(2, 0), ps2_specular_code, 0xff7f0000, TRUE, TRUE},
20567 {D3DVS_VERSION(2, 0), vs2_partial_code, D3DPS_VERSION(2, 0), ps2_texcoord_code, 0xff7f0000, TRUE, TRUE},
20568 {D3DVS_VERSION(3, 0), vs3_partial_code, D3DPS_VERSION(3, 0), ps3_specular_code, 0x007f0000, FALSE, TRUE},
20569 {D3DVS_VERSION(3, 0), vs3_partial_code, D3DPS_VERSION(3, 0), ps3_texcoord_code, 0xff7f0000, TRUE, TRUE},
20571 IDirect3DDevice9 *device;
20572 IDirect3D9 *d3d;
20573 HWND window;
20574 HRESULT hr;
20575 D3DADAPTER_IDENTIFIER9 identifier;
20576 IDirect3DSurface9 *backbuffer;
20577 struct surface_readback rb;
20578 IDirect3DVertexShader9 *vs;
20579 IDirect3DPixelShader9 *ps;
20580 unsigned int i;
20581 ULONG refcount;
20582 D3DCAPS9 caps;
20583 D3DCOLOR color;
20584 BOOL warp;
20586 window = create_window();
20587 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20588 ok(!!d3d, "Failed to create a D3D object.\n");
20589 if (!(device = create_device(d3d, window, window, TRUE)))
20591 skip("Failed to create a D3D device, skipping tests.\n");
20592 IDirect3D9_Release(d3d);
20593 DestroyWindow(window);
20594 return;
20597 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
20598 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
20599 warp = adapter_is_warp(&identifier);
20601 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
20602 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
20604 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
20605 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
20607 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
20608 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
20609 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
20610 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
20611 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
20612 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
20613 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
20614 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
20615 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
20616 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
20617 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
20618 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
20619 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
20620 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#x.\n", hr);
20621 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
20622 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
20624 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
20625 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
20627 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
20629 if (caps.VertexShaderVersion < tests[i].vs_version
20630 || caps.PixelShaderVersion < tests[i].ps_version)
20632 skip("Vertex / pixel shader version not supported, skipping test %u.\n", i);
20633 continue;
20635 if (tests[i].vs)
20637 hr = IDirect3DDevice9_CreateVertexShader(device, tests[i].vs, &vs);
20638 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
20640 else
20642 vs = NULL;
20644 if (tests[i].ps)
20646 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].ps, &ps);
20647 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
20649 else
20651 ps = NULL;
20654 hr = IDirect3DDevice9_SetVertexShader(device, vs);
20655 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
20656 hr = IDirect3DDevice9_SetPixelShader(device, ps);
20657 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
20659 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
20660 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
20662 hr = IDirect3DDevice9_BeginScene(device);
20663 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
20665 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
20666 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20668 hr = IDirect3DDevice9_EndScene(device);
20669 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
20671 get_rt_readback(backbuffer, &rb);
20672 color = get_readback_color(&rb, 320, 240);
20673 ok(color_match(color, tests[i].expected, 1)
20674 || (tests[i].allow_zero_alpha && color_match(color, tests[i].expected & 0x00ffffff, 1))
20675 || (broken(warp && tests[i].broken_warp))
20676 || broken(tests[i].partial && color_match(color & 0x00ff0000, tests[i].expected & 0x00ff0000, 1)),
20677 "Got unexpected color 0x%08x, case %u.\n", color, i);
20678 release_surface_readback(&rb);
20680 if (vs)
20681 IDirect3DVertexShader9_Release(vs);
20682 if (ps)
20683 IDirect3DVertexShader9_Release(ps);
20686 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20687 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20689 IDirect3DSurface9_Release(backbuffer);
20690 refcount = IDirect3DDevice9_Release(device);
20691 ok(!refcount, "Device has %u references left.\n", refcount);
20692 IDirect3D9_Release(d3d);
20693 DestroyWindow(window);
20696 static void test_multisample_init(void)
20698 IDirect3DDevice9 *device;
20699 IDirect3D9 *d3d;
20700 IDirect3DSurface9 *back, *multi;
20701 ULONG refcount;
20702 HWND window;
20703 HRESULT hr;
20704 D3DCOLOR color;
20705 unsigned int x, y;
20706 struct surface_readback rb;
20707 BOOL all_zero = TRUE;
20709 window = create_window();
20710 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20711 ok(!!d3d, "Failed to create a D3D object.\n");
20713 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20714 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
20716 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample init test.\n");
20717 goto done;
20720 if (!(device = create_device(d3d, window, window, TRUE)))
20722 skip("Failed to create a D3D device, skipping tests.\n");
20723 goto done;
20726 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &back);
20727 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
20728 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
20729 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &multi, NULL);
20730 ok(SUCCEEDED(hr), "Failed to create multisampled render target, hr %#x.\n", hr);
20732 hr = IDirect3DDevice9_StretchRect(device, multi, NULL, back, NULL, D3DTEXF_POINT);
20733 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
20735 get_rt_readback(back, &rb);
20736 for (y = 0; y < 480; ++y)
20738 for (x = 0; x < 640; x++)
20740 color = get_readback_color(&rb, x, y);
20741 if (!color_match(color, 0x00000000, 0))
20743 all_zero = FALSE;
20744 break;
20747 if (!all_zero)
20748 break;
20750 release_surface_readback(&rb);
20751 ok(all_zero, "Got unexpected color 0x%08x, position %ux%u.\n", color, x, y);
20753 IDirect3DSurface9_Release(multi);
20754 IDirect3DSurface9_Release(back);
20756 refcount = IDirect3DDevice9_Release(device);
20757 ok(!refcount, "Device has %u references left.\n", refcount);
20759 done:
20760 IDirect3D9_Release(d3d);
20761 DestroyWindow(window);
20764 static void test_texture_blending(void)
20766 #define STATE_END() {0xffffffff, 0xffffffff}
20767 #define IS_STATE_END(s) (s.name == 0xffffffff && s.value == 0xffffffff)
20769 IDirect3DTexture9 *texture_bumpmap, *texture_red;
20770 IDirect3DSurface9 *backbuffer;
20771 struct surface_readback rb;
20772 D3DLOCKED_RECT locked_rect;
20773 IDirect3DDevice9 *device;
20774 unsigned int i, j, k;
20775 IDirect3D9 *d3d;
20776 D3DCOLOR color;
20777 ULONG refcount;
20778 D3DCAPS9 caps;
20779 HWND window;
20780 HRESULT hr;
20782 static const struct
20784 struct vec3 position;
20785 DWORD diffuse;
20787 quad[] =
20789 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
20790 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
20791 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
20792 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
20795 static const float bumpenvmat[4] = {1.0f, 1.0f, 0.0f, 0.0f};
20797 struct texture_stage_state
20799 D3DTEXTURESTAGESTATETYPE name;
20800 DWORD value;
20803 struct texture_stage
20805 enum
20807 TEXTURE_INVALID,
20808 TEXTURE_NONE,
20809 TEXTURE_BUMPMAP,
20810 TEXTURE_RED,
20812 texture;
20813 struct texture_stage_state state[20];
20816 static const struct texture_stage default_stage_state =
20818 TEXTURE_NONE,
20820 {D3DTSS_COLOROP, D3DTOP_DISABLE},
20821 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
20822 {D3DTSS_COLORARG2, D3DTA_CURRENT},
20823 {D3DTSS_ALPHAOP, D3DTOP_DISABLE},
20824 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
20825 {D3DTSS_ALPHAARG2, D3DTA_CURRENT},
20826 {D3DTSS_BUMPENVMAT00, 0},
20827 {D3DTSS_BUMPENVMAT01, 0},
20828 {D3DTSS_BUMPENVMAT10, 0},
20829 {D3DTSS_BUMPENVMAT11, 0},
20830 {D3DTSS_BUMPENVLSCALE, 0},
20831 {D3DTSS_BUMPENVLOFFSET, 0},
20832 {D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE},
20833 {D3DTSS_COLORARG0, D3DTA_CURRENT},
20834 {D3DTSS_ALPHAARG0, D3DTA_CURRENT},
20835 {D3DTSS_RESULTARG, D3DTA_CURRENT},
20836 {D3DTSS_CONSTANT, 0},
20837 STATE_END(),
20841 const struct test
20843 DWORD tex_op_caps;
20844 D3DCOLOR expected_color;
20845 struct texture_stage stage[8];
20847 tests[] =
20850 D3DTEXOPCAPS_DISABLE,
20851 0x80ffff02,
20854 TEXTURE_NONE,
20856 STATE_END(),
20862 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
20863 0x80ffff02,
20866 TEXTURE_NONE,
20868 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
20869 {D3DTSS_COLORARG1, D3DTA_CURRENT},
20870 STATE_END(),
20873 {TEXTURE_INVALID}
20877 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
20878 0x80ffff02,
20881 TEXTURE_NONE,
20883 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
20884 {D3DTSS_COLORARG1, D3DTA_CURRENT},
20885 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20886 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
20887 STATE_END(),
20893 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
20894 0x80ffff02,
20897 TEXTURE_NONE,
20899 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
20900 {D3DTSS_COLORARG1, D3DTA_DIFFUSE},
20901 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20902 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
20903 STATE_END(),
20909 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
20910 0x00000000,
20913 TEXTURE_NONE,
20915 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
20916 {D3DTSS_COLORARG1, D3DTA_TEMP},
20917 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20918 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
20919 STATE_END(),
20925 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_SUBTRACT,
20926 0x80f0f000,
20929 TEXTURE_NONE,
20931 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
20932 {D3DTSS_COLORARG1, D3DTA_CURRENT},
20933 STATE_END(),
20937 TEXTURE_NONE,
20939 {D3DTSS_COLOROP, D3DTOP_SUBTRACT},
20940 {D3DTSS_COLORARG1, D3DTA_CURRENT},
20941 {D3DTSS_COLORARG2, D3DTA_CONSTANT},
20942 {D3DTSS_CONSTANT, 0x0f0f0f0f},
20943 STATE_END(),
20946 {TEXTURE_INVALID}
20950 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_SUBTRACT,
20951 0x71f0f000,
20954 TEXTURE_NONE,
20956 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
20957 {D3DTSS_COLORARG1, D3DTA_CURRENT},
20958 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20959 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
20960 STATE_END(),
20964 TEXTURE_NONE,
20966 {D3DTSS_COLOROP, D3DTOP_SUBTRACT},
20967 {D3DTSS_COLORARG1, D3DTA_CURRENT},
20968 {D3DTSS_COLORARG2, D3DTA_CONSTANT},
20969 {D3DTSS_ALPHAOP, D3DTOP_SUBTRACT},
20970 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
20971 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
20972 {D3DTSS_CONSTANT, 0x0f0f0f0f},
20973 STATE_END(),
20976 {TEXTURE_INVALID}
20981 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
20982 0x80ff0000,
20985 TEXTURE_BUMPMAP,
20987 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
20988 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
20989 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
20990 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
20991 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
20992 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20993 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
20994 STATE_END(),
20999 TEXTURE_RED,
21001 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21002 STATE_END(),
21005 {TEXTURE_INVALID}
21009 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
21010 0x80ff0000,
21013 TEXTURE_BUMPMAP,
21015 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21016 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21017 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21018 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21019 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21020 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21021 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
21022 STATE_END(),
21026 TEXTURE_RED,
21028 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21029 STATE_END(),
21032 {TEXTURE_INVALID}
21036 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
21037 0x80ff0000,
21040 TEXTURE_BUMPMAP,
21042 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21043 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21044 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21045 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21046 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21047 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21048 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21049 STATE_END(),
21053 TEXTURE_RED,
21055 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21056 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21057 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21058 STATE_END(),
21061 {TEXTURE_INVALID}
21065 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
21066 0x00ff0000,
21069 TEXTURE_BUMPMAP,
21071 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21072 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21073 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21074 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21075 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21076 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21077 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21078 STATE_END(),
21082 TEXTURE_RED,
21084 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21085 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21086 {D3DTSS_COLORARG2, D3DTA_CURRENT},
21087 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21088 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21089 STATE_END(),
21092 {TEXTURE_INVALID}
21096 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
21097 0x80ff0000,
21100 TEXTURE_BUMPMAP,
21102 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21103 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21104 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21105 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21106 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21107 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21108 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21109 STATE_END(),
21113 TEXTURE_RED,
21115 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21116 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21117 {D3DTSS_COLORARG2, D3DTA_CURRENT},
21118 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21119 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21120 STATE_END(),
21123 {TEXTURE_INVALID}
21128 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
21129 | D3DTEXOPCAPS_ADD,
21130 0x80ff0000,
21133 TEXTURE_BUMPMAP,
21135 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21136 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21137 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21138 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21139 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21140 {D3DTSS_ALPHAOP, D3DTOP_ADD},
21141 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
21142 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
21143 {D3DTSS_CONSTANT, 0x0fffffff},
21144 STATE_END(),
21148 TEXTURE_RED,
21150 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21151 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21152 {D3DTSS_COLORARG2, D3DTA_CURRENT},
21153 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21154 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21155 STATE_END(),
21158 {TEXTURE_INVALID}
21162 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
21163 | D3DTEXOPCAPS_MODULATE2X,
21164 0x80ff0000,
21167 TEXTURE_BUMPMAP,
21169 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21170 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21171 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21172 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21173 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21174 {D3DTSS_ALPHAOP, D3DTOP_MODULATE2X},
21175 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
21176 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
21177 {D3DTSS_CONSTANT, 0x01ffffff},
21178 STATE_END(),
21182 TEXTURE_RED,
21184 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21185 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21186 {D3DTSS_COLORARG2, D3DTA_CURRENT},
21187 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21188 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21189 STATE_END(),
21192 {TEXTURE_INVALID}
21196 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
21197 | D3DTEXOPCAPS_MODULATE2X,
21198 0x80ffff00,
21201 TEXTURE_BUMPMAP,
21203 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21204 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21205 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21206 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21207 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21208 {D3DTSS_ALPHAOP, D3DTOP_MODULATE2X},
21209 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21210 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
21211 {D3DTSS_CONSTANT, 0x01ffffff},
21212 STATE_END(),
21216 TEXTURE_RED,
21218 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21219 {D3DTSS_COLORARG1, D3DTA_CURRENT},
21220 {D3DTSS_COLORARG2, D3DTA_CURRENT},
21221 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21222 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21223 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
21224 {D3DTSS_ALPHAARG0, D3DTA_CONSTANT},
21225 STATE_END(),
21228 {TEXTURE_INVALID}
21232 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
21233 0x01234567,
21236 TEXTURE_NONE,
21238 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21239 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
21240 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21241 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
21242 {D3DTSS_RESULTARG, D3DTA_TEMP},
21243 {D3DTSS_CONSTANT, 0x01234567},
21244 STATE_END(),
21248 TEXTURE_BUMPMAP,
21250 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21251 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21252 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21253 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21254 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21255 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21256 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21257 {D3DTSS_RESULTARG, D3DTA_TEMP},
21258 STATE_END(),
21262 TEXTURE_RED,
21264 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21265 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21266 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21267 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
21268 STATE_END(),
21272 TEXTURE_NONE,
21274 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21275 {D3DTSS_COLORARG1, D3DTA_TEMP},
21276 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21277 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21278 STATE_END(),
21281 {TEXTURE_INVALID}
21285 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
21286 0x00234567,
21289 TEXTURE_NONE,
21291 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21292 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
21293 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21294 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
21295 {D3DTSS_RESULTARG, D3DTA_TEMP},
21296 {D3DTSS_CONSTANT, 0x01234567},
21297 STATE_END(),
21301 TEXTURE_BUMPMAP,
21303 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21304 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21305 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21306 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21307 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21308 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21309 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21310 STATE_END(),
21314 TEXTURE_RED,
21316 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21317 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21318 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21319 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
21320 STATE_END(),
21324 TEXTURE_NONE,
21326 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21327 {D3DTSS_COLORARG1, D3DTA_TEMP},
21328 STATE_END(),
21331 {TEXTURE_INVALID}
21335 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
21336 0x01234567,
21339 TEXTURE_NONE,
21341 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21342 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
21343 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21344 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
21345 {D3DTSS_RESULTARG, D3DTA_TEMP},
21346 {D3DTSS_CONSTANT, 0x01234567},
21347 STATE_END(),
21351 TEXTURE_BUMPMAP,
21353 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21354 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21355 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21356 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21357 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21358 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21359 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21360 {D3DTSS_RESULTARG, D3DTA_TEMP},
21361 STATE_END(),
21365 TEXTURE_RED,
21367 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21368 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21369 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21370 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
21371 STATE_END(),
21375 TEXTURE_NONE,
21377 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21378 {D3DTSS_COLORARG1, D3DTA_TEMP},
21379 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21380 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21381 STATE_END(),
21384 {TEXTURE_INVALID}
21388 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
21389 0x01234567,
21392 TEXTURE_NONE,
21394 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21395 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
21396 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21397 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
21398 {D3DTSS_RESULTARG, D3DTA_CURRENT},
21399 {D3DTSS_CONSTANT, 0x01234567},
21400 STATE_END(),
21404 TEXTURE_BUMPMAP,
21406 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21407 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21408 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21409 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21410 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21411 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21412 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21413 {D3DTSS_RESULTARG, D3DTA_TEMP},
21414 STATE_END(),
21418 TEXTURE_RED,
21420 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21421 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21422 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21423 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
21424 {D3DTSS_RESULTARG, D3DTA_TEMP},
21425 STATE_END(),
21429 TEXTURE_NONE,
21431 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21432 {D3DTSS_COLORARG1, D3DTA_CURRENT},
21433 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21434 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21435 {D3DTSS_RESULTARG, D3DTA_CURRENT},
21436 STATE_END(),
21439 {TEXTURE_INVALID}
21444 window = create_window();
21445 d3d = Direct3DCreate9(D3D_SDK_VERSION);
21446 ok(!!d3d, "Failed to create a D3D object.\n");
21447 if (!(device = create_device(d3d, window, window, TRUE)))
21449 skip("Failed to create a D3D device.\n");
21450 goto done;
21453 memset(&caps, 0, sizeof(caps));
21454 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
21455 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr %#x.\n", hr);
21457 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
21459 skip("D3DPMISCCAPS_TSSARGTEMP not supported.\n");
21460 IDirect3DDevice9_Release(device);
21461 goto done;
21464 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_PERSTAGECONSTANT))
21466 skip("D3DPMISCCAPS_PERSTAGECONSTANT not supported.\n");
21467 IDirect3DDevice9_Release(device);
21468 goto done;
21471 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
21472 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_V8U8)))
21474 skip("D3DFMT_V8U8 not supported for legacy bump mapping.\n");
21475 IDirect3DDevice9_Release(device);
21476 goto done;
21479 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
21480 ok(hr == D3D_OK, "Can't get back buffer, hr %#x.\n", hr);
21482 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture_bumpmap, NULL);
21483 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr %#x.\n", hr);
21484 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture_red, NULL);
21485 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr %#x.\n", hr);
21487 memset(&locked_rect, 0, sizeof(locked_rect));
21488 hr = IDirect3DTexture9_LockRect(texture_bumpmap, 0, &locked_rect, NULL, 0);
21489 ok(SUCCEEDED(hr), "LockRect failed, hr %#x.\n", hr);
21490 *((WORD *)locked_rect.pBits) = 0xff00;
21491 hr = IDirect3DTexture9_UnlockRect(texture_bumpmap, 0);
21492 ok(SUCCEEDED(hr), "UnlockRect failed, hr %#x.\n", hr);
21494 memset(&locked_rect, 0, sizeof(locked_rect));
21495 hr = IDirect3DTexture9_LockRect(texture_red, 0, &locked_rect, NULL, 0);
21496 ok(SUCCEEDED(hr), "LockRect failed, hr %#x.\n", hr);
21497 *((DWORD *)locked_rect.pBits) = 0x00ff0000;
21498 hr = IDirect3DTexture9_UnlockRect(texture_red, 0);
21499 ok(SUCCEEDED(hr), "UnlockRect failed, hr %#x.\n", hr);
21501 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
21502 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
21503 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
21504 ok(hr == D3D_OK, "Failed to disable lighting, hr %#x.\n", hr);
21506 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
21508 const struct test *current_test = &tests[i];
21510 if ((caps.TextureOpCaps & current_test->tex_op_caps) != current_test->tex_op_caps)
21512 skip("Texture operations %#x not supported.\n", current_test->tex_op_caps);
21513 continue;
21516 for (j = 0; j < caps.MaxTextureBlendStages; ++j)
21518 IDirect3DTexture9 *current_texture = NULL;
21520 for (k = 0; !IS_STATE_END(default_stage_state.state[k]); ++k)
21522 hr = IDirect3DDevice9_SetTextureStageState(device, j,
21523 default_stage_state.state[k].name, default_stage_state.state[k].value);
21524 ok(SUCCEEDED(hr), "Test %u: SetTextureStageState failed, hr %#x.\n", i, hr);
21527 if (current_test->stage[j].texture != TEXTURE_INVALID)
21529 const struct texture_stage_state *current_state = current_test->stage[j].state;
21531 switch (current_test->stage[j].texture)
21533 case TEXTURE_RED:
21534 current_texture = texture_red;
21535 break;
21536 case TEXTURE_BUMPMAP:
21537 current_texture = texture_bumpmap;
21538 break;
21539 default:
21540 current_texture = NULL;
21541 break;
21544 for (k = 0; !IS_STATE_END(current_state[k]); ++k)
21546 hr = IDirect3DDevice9_SetTextureStageState(device, j,
21547 current_state[k].name, current_state[k].value);
21548 ok(SUCCEEDED(hr), "Test %u: SetTextureStageState failed, hr %#x.\n", i, hr);
21552 hr = IDirect3DDevice9_SetTexture(device, j, (IDirect3DBaseTexture9 *)current_texture);
21553 ok(SUCCEEDED(hr), "Test %u: SetTexture failed, hr %#x.\n", i, hr);
21556 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
21557 ok(hr == D3D_OK, "Test %u: IDirect3DDevice9_Clear failed, hr %#x.\n", i, hr);
21559 hr = IDirect3DDevice9_BeginScene(device);
21560 ok(SUCCEEDED(hr), "Test %u: BeginScene failed, hr %#x.\n", i, hr);
21561 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
21562 ok(SUCCEEDED(hr), "Test %u: DrawPrimitiveUP failed, hr %#x.\n", i, hr);
21563 hr = IDirect3DDevice9_EndScene(device);
21564 ok(SUCCEEDED(hr), "Test %u: EndScene failed, hr %#x.\n", i, hr);
21566 get_rt_readback(backbuffer, &rb);
21567 color = get_readback_color(&rb, 320, 240);
21568 ok(color_match(color, current_test->expected_color, 1),
21569 "Test %u: Got color 0x%08x, expected 0x%08x.\n", i, color, current_test->expected_color);
21570 release_surface_readback(&rb);
21571 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21572 ok(SUCCEEDED(hr), "Test %u: Present failed, hr %#x.\n", i, hr);
21575 IDirect3DTexture9_Release(texture_bumpmap);
21576 IDirect3DTexture9_Release(texture_red);
21577 IDirect3DSurface9_Release(backbuffer);
21578 refcount = IDirect3DDevice9_Release(device);
21579 ok(!refcount, "Device has %u references left.\n", refcount);
21580 done:
21581 IDirect3D9_Release(d3d);
21582 DestroyWindow(window);
21585 static void test_color_clamping(void)
21587 static const D3DMATRIX mat =
21589 1.0f, 0.0f, 0.0f, 0.0f,
21590 0.0f, 1.0f, 0.0f, 0.0f,
21591 0.0f, 0.0f, 1.0f, 0.0f,
21592 0.0f, 0.0f, 0.0f, 1.0f,
21593 }}};
21594 static const struct vec3 quad[] =
21596 {-1.0f, -1.0f, 0.1f},
21597 {-1.0f, 1.0f, 0.1f},
21598 { 1.0f, -1.0f, 0.1f},
21599 { 1.0f, 1.0f, 0.1f},
21601 static const DWORD vs1_code[] =
21603 0xfffe0101, /* vs_1_1 */
21604 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
21605 0x00000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
21606 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
21607 0x00000002, 0xd00f0000, 0xa0e40000, 0xa0e40000, /* add oD0, c0, c0 */
21608 0x00000002, 0xd00f0001, 0xa0e40000, 0xa0e40000, /* add oD1, c0, c0 */
21609 0x0000ffff
21611 static const DWORD vs2_code[] =
21613 0xfffe0200, /* vs_2_0 */
21614 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
21615 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
21616 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
21617 0x03000002, 0xd00f0000, 0xa0e40000, 0xa0e40000, /* add oD0, c0, c0 */
21618 0x03000002, 0xd00f0001, 0xa0e40000, 0xa0e40000, /* add oD1, c0, c0 */
21619 0x0000ffff
21621 static const DWORD vs3_code[] =
21623 0xfffe0300, /* vs_3_0 */
21624 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
21625 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
21626 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
21627 0x0200001f, 0x8001000a, 0xe00f0002, /* dcl_color1 o2 */
21628 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
21629 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
21630 0x03000002, 0xe00f0001, 0xa0e40000, 0xa0e40000, /* add o1, c0, c0 */
21631 0x03000002, 0xe00f0002, 0xa0e40000, 0xa0e40000, /* add o2, c0, c0 */
21632 0x0000ffff
21634 static const DWORD ps1_code[] =
21636 0xffff0101, /* ps_1_1 */
21637 0x00000051, 0xa00f0000, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000, /* def c0, 0.25, 0.25, 0.25, 0.25 */
21638 0x00000002, 0x800f0000, 0x90e40000, 0x90e40001, /* add r0, v0, v1 */
21639 0x00000005, 0x800f0000, 0x80e40000, 0xa0e40000, /* mul r0, r0, c0 */
21640 0x0000ffff
21642 static const DWORD ps2_code[] =
21644 0xffff0200, /* ps_2_0 */
21645 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
21646 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
21647 0x05000051, 0xa00f0000, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000, /* def c0, 0.25, 0.25, 0.25, 0.25 */
21648 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
21649 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
21650 0x03000005, 0x800f0000, 0x80e40000, 0xa0e40000, /* mul r0, r0, c0 */
21651 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
21652 0x0000ffff
21654 static const DWORD ps3_code[] =
21656 0xffff0300, /* ps_3_0 */
21657 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
21658 0x0200001f, 0x8001000a, 0x900f0001, /* dcl_color1 v1 */
21659 0x05000051, 0xa00f0000, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000, /* def c0, 0.25, 0.25, 0.25, 0.25 */
21660 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
21661 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
21662 0x03000005, 0x800f0800, 0x80e40000, 0xa0e40000, /* mul oC0, r0, c0 */
21663 0x0000ffff
21665 static const struct
21667 DWORD vs_version;
21668 const DWORD *vs;
21669 DWORD ps_version;
21670 const DWORD *ps;
21671 D3DCOLOR expected, broken;
21673 tests[] =
21675 {0, NULL, 0, NULL, 0x00404040},
21676 {0, NULL, D3DPS_VERSION(1, 1), ps1_code, 0x00404040, 0x00808080},
21677 {D3DVS_VERSION(1, 1), vs1_code, 0, NULL, 0x00404040},
21678 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_code, 0x007f7f7f},
21679 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_code, 0x007f7f7f},
21680 {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_code, 0x00ffffff},
21682 IDirect3DVertexShader9 *vs;
21683 IDirect3DPixelShader9 *ps;
21684 IDirect3DDevice9 *device;
21685 IDirect3D9 *d3d9;
21686 unsigned int i;
21687 ULONG refcount;
21688 D3DCOLOR color;
21689 D3DCAPS9 caps;
21690 HWND window;
21691 HRESULT hr;
21693 window = create_window();
21694 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
21695 ok(!!d3d9, "Failed to create a D3D object.\n");
21696 if (!(device = create_device(d3d9, window, window, TRUE)))
21698 skip("Failed to create a D3D device, skipping tests.\n");
21699 IDirect3D9_Release(d3d9);
21700 DestroyWindow(window);
21701 return;
21704 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
21705 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
21707 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
21708 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
21709 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
21710 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
21711 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
21712 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
21713 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
21714 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
21715 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
21716 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
21717 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
21718 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
21719 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
21720 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#x.\n", hr);
21721 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
21722 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
21723 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
21724 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
21726 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xff404040);
21727 ok(SUCCEEDED(hr), "Failed to set texture factor, hr %#x.\n", hr);
21728 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
21729 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
21730 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
21731 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
21732 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_SPECULAR);
21733 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
21734 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_MODULATE);
21735 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
21736 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
21737 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
21738 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
21739 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
21741 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
21742 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
21744 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
21746 if (caps.VertexShaderVersion < tests[i].vs_version
21747 || caps.PixelShaderVersion < tests[i].ps_version)
21749 skip("Vertex / pixel shader version not supported, skipping test %u.\n", i);
21750 continue;
21752 if (tests[i].vs)
21754 hr = IDirect3DDevice9_CreateVertexShader(device, tests[i].vs, &vs);
21755 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
21757 else
21759 vs = NULL;
21761 if (tests[i].ps)
21763 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].ps, &ps);
21764 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
21766 else
21768 ps = NULL;
21771 hr = IDirect3DDevice9_SetVertexShader(device, vs);
21772 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
21773 hr = IDirect3DDevice9_SetPixelShader(device, ps);
21774 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
21776 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
21777 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21779 hr = IDirect3DDevice9_BeginScene(device);
21780 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21782 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
21783 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
21785 hr = IDirect3DDevice9_EndScene(device);
21786 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
21788 color = getPixelColor(device, 320, 240);
21789 ok(color_match(color, tests[i].expected, 1) || broken(color_match(color, tests[i].broken, 1)),
21790 "Got unexpected color 0x%08x, case %u.\n", color, i);
21792 if (vs)
21793 IDirect3DVertexShader9_Release(vs);
21794 if (ps)
21795 IDirect3DVertexShader9_Release(ps);
21798 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21799 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
21801 refcount = IDirect3DDevice9_Release(device);
21802 ok(!refcount, "Device has %u references left.\n", refcount);
21803 IDirect3D9_Release(d3d9);
21804 DestroyWindow(window);
21807 static void test_line_antialiasing_blending(void)
21809 IDirect3DDevice9 *device;
21810 IDirect3D9 *d3d9;
21811 ULONG refcount;
21812 D3DCOLOR color;
21813 D3DCAPS9 caps;
21814 HWND window;
21815 HRESULT hr;
21817 static const struct
21819 struct vec3 position;
21820 DWORD diffuse;
21822 green_quad[] =
21824 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
21825 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
21826 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
21827 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
21829 static const struct
21831 struct vec3 position;
21832 DWORD diffuse;
21834 red_quad[] =
21836 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
21837 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
21838 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
21839 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
21842 window = create_window();
21843 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
21844 ok(!!d3d9, "Failed to create a D3D object.\n");
21845 if (!(device = create_device(d3d9, window, window, TRUE)))
21847 skip("Failed to create a D3D device.\n");
21848 IDirect3D9_Release(d3d9);
21849 DestroyWindow(window);
21850 return;
21853 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
21854 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
21855 trace("Line antialiasing support: %#x.\n", caps.LineCaps & D3DLINECAPS_ANTIALIAS);
21857 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
21858 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
21859 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
21860 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
21861 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
21862 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
21864 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
21865 ok(SUCCEEDED(hr), "Failed to enable blending, hr %#x.\n", hr);
21866 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_BLENDOP, D3DBLENDOP_ADD);
21867 ok(SUCCEEDED(hr), "Failed to set blend op, hr %#x.\n", hr);
21868 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
21869 ok(SUCCEEDED(hr), "Failed to set src blend, hr %#x.\n", hr);
21870 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_DESTALPHA);
21871 ok(SUCCEEDED(hr), "Failed to set dest blend, hr %#x.\n", hr);
21873 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
21874 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
21875 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
21876 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
21877 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
21878 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#x.\n", hr);
21879 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
21880 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#x.\n", hr);
21882 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
21883 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
21885 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
21886 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21887 hr = IDirect3DDevice9_BeginScene(device);
21888 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21889 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
21890 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
21891 hr = IDirect3DDevice9_EndScene(device);
21892 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
21893 color = getPixelColor(device, 320, 240);
21894 ok(color_match(color, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color);
21896 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
21897 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21898 hr = IDirect3DDevice9_BeginScene(device);
21899 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21900 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
21901 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
21902 hr = IDirect3DDevice9_EndScene(device);
21903 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
21904 color = getPixelColor(device, 320, 240);
21905 ok(color_match(color, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color);
21907 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
21908 ok(SUCCEEDED(hr), "Failed to disable blending, hr %#x.\n", hr);
21910 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
21911 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21912 hr = IDirect3DDevice9_BeginScene(device);
21913 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21914 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
21915 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
21916 hr = IDirect3DDevice9_EndScene(device);
21917 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
21918 color = getPixelColor(device, 320, 240);
21919 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
21921 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
21922 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21923 hr = IDirect3DDevice9_BeginScene(device);
21924 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21925 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
21926 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
21927 hr = IDirect3DDevice9_EndScene(device);
21928 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
21929 color = getPixelColor(device, 320, 240);
21930 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
21932 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ANTIALIASEDLINEENABLE, TRUE);
21933 ok(SUCCEEDED(hr), "Failed to enable line antialiasing, hr %#x.\n", hr);
21935 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
21936 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21937 hr = IDirect3DDevice9_BeginScene(device);
21938 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21939 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
21940 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
21941 hr = IDirect3DDevice9_EndScene(device);
21942 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
21943 color = getPixelColor(device, 320, 240);
21944 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
21946 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
21947 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
21948 hr = IDirect3DDevice9_BeginScene(device);
21949 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
21950 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
21951 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
21952 hr = IDirect3DDevice9_EndScene(device);
21953 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
21954 color = getPixelColor(device, 320, 240);
21955 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
21957 refcount = IDirect3DDevice9_Release(device);
21958 ok(!refcount, "Device has %u references left.\n", refcount);
21959 IDirect3D9_Release(d3d9);
21960 DestroyWindow(window);
21963 static void test_dsy(void)
21965 static const DWORD vs_code[] =
21967 0xfffe0300, /* vs_3_0 */
21968 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
21969 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
21970 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
21971 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
21972 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
21973 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
21974 0x0000ffff
21976 static const DWORD ps_code[] =
21978 0xffff0300, /* ps_3_0 */
21979 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
21980 0x05000051, 0xa00f0000, 0x43700000, 0x3f000000, 0x00000000, 0x00000000, /* def c0, 240.0, 0.5, 0.0, 0.0 */
21981 0x0200005c, 0x800f0000, 0x90e40000, /* dsy r0, v0 */
21982 0x03000005, 0x800f0000, 0x80e40000, 0xa0000000, /* mul r0, r0, c0.x */
21983 0x03000002, 0x800f0800, 0x80e40000, 0xa0550000, /* add oC0, r0, c0.y */
21984 0x0000ffff
21986 static const struct
21988 struct vec3 pos;
21989 D3DCOLOR color;
21991 quad[] =
21993 {{-1.0f, -1.0f, 0.1f}, 0x00ff0000},
21994 {{-1.0f, 1.0f, 0.1f}, 0x0000ff00},
21995 {{ 1.0f, -1.0f, 0.1f}, 0x00ff0000},
21996 {{ 1.0f, 1.0f, 0.1f}, 0x0000ff00},
21998 IDirect3DSurface9 *backbuffer, *rt;
21999 IDirect3DVertexShader9 *vs;
22000 IDirect3DPixelShader9 *ps;
22001 IDirect3DDevice9 *device;
22002 IDirect3D9 *d3d;
22003 ULONG refcount;
22004 D3DCAPS9 caps;
22005 DWORD color;
22006 HWND window;
22007 HRESULT hr;
22009 window = create_window();
22010 d3d = Direct3DCreate9(D3D_SDK_VERSION);
22011 ok(!!d3d, "Failed to create a D3D object.\n");
22012 if (!(device = create_device(d3d, window, window, TRUE)))
22014 skip("Failed to create a D3D device, skipping tests.\n");
22015 goto done;
22018 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
22019 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
22020 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
22022 skip("No ps_3_0 support, skipping dsy tests.\n");
22023 IDirect3DDevice9_Release(device);
22024 goto done;
22027 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
22028 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
22030 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
22031 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
22032 ok(SUCCEEDED(hr), "Failed to create offscreen render target, hr %#x.\n", hr);
22033 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
22034 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
22036 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
22037 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
22038 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
22039 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
22041 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
22042 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
22043 hr = IDirect3DDevice9_SetVertexShader(device, vs);
22044 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
22045 hr = IDirect3DDevice9_SetPixelShader(device, ps);
22046 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
22048 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
22049 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22050 hr = IDirect3DDevice9_BeginScene(device);
22051 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22052 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
22053 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
22054 hr = IDirect3DDevice9_EndScene(device);
22055 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22057 color = getPixelColor(device, 360, 240);
22058 ok(color_match(color, 0x00ff007f, 1), "Got unexpected color 0x%08x.\n", color);
22060 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
22061 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
22063 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
22064 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22065 hr = IDirect3DDevice9_BeginScene(device);
22066 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22067 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
22068 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
22069 hr = IDirect3DDevice9_EndScene(device);
22070 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22072 color = getPixelColor(device, 360, 240);
22073 ok(color_match(color, 0x00ff007f, 1), "Got unexpected color 0x%08x.\n", color);
22075 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
22076 ok(SUCCEEDED(hr), "Failed to present frame, hr %#x.\n", hr);
22078 IDirect3DSurface9_Release(rt);
22079 IDirect3DSurface9_Release(backbuffer);
22080 IDirect3DVertexShader9_Release(vs);
22081 IDirect3DPixelShader9_Release(ps);
22083 refcount = IDirect3DDevice9_Release(device);
22084 ok(!refcount, "Device has %u references left.\n", refcount);
22085 done:
22086 IDirect3D9_Release(d3d);
22087 DestroyWindow(window);
22090 static void test_evict_bound_resources(void)
22092 IDirect3DVertexBuffer9 *vb;
22093 IDirect3DIndexBuffer9 *ib;
22094 IDirect3DDevice9 *device;
22095 IDirect3D9 *d3d9;
22096 ULONG refcount;
22097 D3DCOLOR color;
22098 HWND window;
22099 void *data;
22100 HRESULT hr;
22102 static const struct
22104 struct vec3 position;
22105 DWORD diffuse;
22107 green_quad[] =
22109 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
22110 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
22111 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
22112 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
22114 static const unsigned short indices[] = {0, 1, 2, 3, 2, 1};
22116 window = create_window();
22117 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
22118 ok(!!d3d9, "Failed to create a D3D object.\n");
22120 if (!(device = create_device(d3d9, window, window, TRUE)))
22122 skip("Failed to create a D3D device.\n");
22123 IDirect3D9_Release(d3d9);
22124 DestroyWindow(window);
22125 return;
22128 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0,
22129 D3DFMT_INDEX16, D3DPOOL_MANAGED, &ib, NULL);
22130 ok(SUCCEEDED(hr), "Failed to create index buffer, hr %#x.\n", hr);
22132 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(green_quad), 0,
22133 D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &vb, NULL);
22134 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
22136 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
22137 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
22138 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
22139 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
22140 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
22141 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
22143 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
22144 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
22146 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(green_quad), &data, 0);
22147 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#x.\n", hr);
22148 memcpy(data, green_quad, sizeof(green_quad));
22149 hr = IDirect3DVertexBuffer9_Unlock(vb);
22150 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#x.\n", hr);
22152 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), &data, 0);
22153 ok(hr == D3D_OK, "Failed to lock index buffer, hr %#x.\n", hr);
22154 memcpy(data, indices, sizeof(indices));
22155 hr = IDirect3DIndexBuffer9_Unlock(ib);
22156 ok(hr == D3D_OK, "Failed to unlock index buffer, hr %#x.\n", hr);
22158 hr = IDirect3DDevice9_SetIndices(device, ib);
22159 ok(hr == D3D_OK, "Failed to set index buffer, hr %#x.\n", hr);
22160 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(*green_quad));
22161 ok(hr == D3D_OK, "Failed to set stream source, hr %#x.\n", hr);
22163 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
22164 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22165 hr = IDirect3DDevice9_BeginScene(device);
22166 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22167 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
22168 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22169 hr = IDirect3DDevice9_EndScene(device);
22170 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22171 color = getPixelColor(device, 320, 240);
22172 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
22174 hr = IDirect3DDevice9_EvictManagedResources(device);
22175 ok(hr == D3D_OK, "Failed to evict managed resources, hr %#x.\n", hr);
22177 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
22178 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22179 hr = IDirect3DDevice9_BeginScene(device);
22180 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22181 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
22182 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22183 hr = IDirect3DDevice9_EndScene(device);
22184 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22185 color = getPixelColor(device, 320, 240);
22186 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
22188 IDirect3DIndexBuffer9_Release(ib);
22189 IDirect3DVertexBuffer9_Release(vb);
22190 refcount = IDirect3DDevice9_Release(device);
22191 ok(!refcount, "Device has %u references left.\n", refcount);
22192 IDirect3D9_Release(d3d9);
22193 DestroyWindow(window);
22196 /* This test shows that 0xffff is valid index in D3D9. */
22197 static void test_max_index16(void)
22199 static const struct vertex
22201 struct vec3 position;
22202 DWORD diffuse;
22204 green_quad[] =
22206 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22207 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22208 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22209 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22211 static const unsigned short indices[] = {0, 1, 2, 0xffff};
22212 static const unsigned int vertex_count = 0xffff + 1;
22214 D3DADAPTER_IDENTIFIER9 identifier;
22215 IDirect3DVertexBuffer9 *vb;
22216 IDirect3DIndexBuffer9 *ib;
22217 IDirect3DDevice9 *device;
22218 struct vertex *vb_data;
22219 IDirect3D9 *d3d9;
22220 ULONG refcount;
22221 D3DCOLOR color;
22222 D3DCAPS9 caps;
22223 HWND window;
22224 void *data;
22225 HRESULT hr;
22226 BOOL warp;
22228 window = create_window();
22229 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
22230 ok(!!d3d9, "Failed to create a D3D object.\n");
22232 hr = IDirect3D9_GetAdapterIdentifier(d3d9, D3DADAPTER_DEFAULT, 0, &identifier);
22233 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
22234 warp = adapter_is_warp(&identifier);
22236 if (!(device = create_device(d3d9, window, window, TRUE)))
22238 skip("Failed to create a D3D device.\n");
22239 IDirect3D9_Release(d3d9);
22240 DestroyWindow(window);
22241 return;
22244 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
22245 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
22246 if (caps.MaxVertexIndex < 0xffff)
22248 skip("Max vertex index is lower than 0xffff (%#x).\n", caps.MaxVertexIndex);
22249 IDirect3DDevice9_Release(device);
22250 IDirect3D9_Release(d3d9);
22251 DestroyWindow(window);
22252 return;
22255 hr = IDirect3DDevice9_CreateVertexBuffer(device, vertex_count * sizeof(*green_quad), 0,
22256 D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &vb, NULL);
22257 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
22259 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0,
22260 D3DFMT_INDEX16, D3DPOOL_MANAGED, &ib, NULL);
22261 ok(SUCCEEDED(hr), "Failed to create index buffer, hr %#x.\n", hr);
22263 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
22264 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
22265 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
22266 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
22267 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
22268 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
22270 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
22271 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
22273 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(green_quad), (void **)&vb_data, 0);
22274 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#x.\n", hr);
22275 vb_data[0] = green_quad[0];
22276 vb_data[1] = green_quad[1];
22277 vb_data[2] = green_quad[2];
22278 vb_data[0xffff] = green_quad[3];
22279 hr = IDirect3DVertexBuffer9_Unlock(vb);
22280 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#x.\n", hr);
22282 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), &data, 0);
22283 ok(hr == D3D_OK, "Failed to lock index buffer, hr %#x.\n", hr);
22284 memcpy(data, indices, sizeof(indices));
22285 hr = IDirect3DIndexBuffer9_Unlock(ib);
22286 ok(hr == D3D_OK, "Failed to unlock index buffer, hr %#x.\n", hr);
22288 hr = IDirect3DDevice9_SetIndices(device, ib);
22289 ok(hr == D3D_OK, "Failed to set index buffer, hr %#x.\n", hr);
22290 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(struct vertex));
22291 ok(hr == D3D_OK, "Failed to set stream source, hr %#x.\n", hr);
22293 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
22294 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22295 hr = IDirect3DDevice9_BeginScene(device);
22296 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22297 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 0, vertex_count, 0, 2);
22298 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22299 hr = IDirect3DDevice9_EndScene(device);
22300 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22301 color = getPixelColor(device, 20, 20);
22302 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
22303 color = getPixelColor(device, 320, 240);
22304 ok(color_match(color, 0x0000ff00, 1) || broken(warp), "Got unexpected color 0x%08x.\n", color);
22305 color = getPixelColor(device, 620, 460);
22306 ok(color_match(color, 0x0000ff00, 1) || broken(warp), "Got unexpected color 0x%08x.\n", color);
22308 IDirect3DIndexBuffer9_Release(ib);
22309 IDirect3DVertexBuffer9_Release(vb);
22310 refcount = IDirect3DDevice9_Release(device);
22311 ok(!refcount, "Device has %u references left.\n", refcount);
22312 IDirect3D9_Release(d3d9);
22313 DestroyWindow(window);
22316 static void test_backbuffer_resize(void)
22318 D3DPRESENT_PARAMETERS present_parameters = {0};
22319 IDirect3DSurface9 *backbuffer;
22320 IDirect3DDevice9 *device;
22321 IDirect3D9 *d3d;
22322 D3DCOLOR color;
22323 ULONG refcount;
22324 HWND window;
22325 HRESULT hr;
22327 static const struct
22329 struct vec3 position;
22330 DWORD diffuse;
22332 quad[] =
22334 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22335 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22336 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22337 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
22340 window = create_window();
22341 d3d = Direct3DCreate9(D3D_SDK_VERSION);
22342 ok(!!d3d, "Failed to create a D3D object.\n");
22343 if (!(device = create_device(d3d, window, window, TRUE)))
22345 skip("Failed to create a D3D device.\n");
22346 goto done;
22349 /* Wine d3d9 implementation had a bug which was triggered by a
22350 * SetRenderTarget() call with an unreferenced surface. */
22351 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
22352 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
22353 refcount = IDirect3DSurface9_Release(backbuffer);
22354 ok(!refcount, "Surface has %u references left.\n", refcount);
22355 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
22356 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
22357 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
22358 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
22360 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
22361 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22362 color = getPixelColor(device, 1, 1);
22363 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
22365 present_parameters.BackBufferWidth = 800;
22366 present_parameters.BackBufferHeight = 600;
22367 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
22368 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
22369 present_parameters.hDeviceWindow = NULL;
22370 present_parameters.Windowed = TRUE;
22371 present_parameters.EnableAutoDepthStencil = TRUE;
22372 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
22373 hr = IDirect3DDevice9_Reset(device, &present_parameters);
22374 ok(SUCCEEDED(hr), "Failed to reset, hr %#x.\n", hr);
22376 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
22377 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
22378 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
22379 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
22380 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
22381 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
22382 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
22383 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
22385 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
22386 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
22387 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
22388 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
22389 IDirect3DSurface9_Release(backbuffer);
22391 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
22392 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22393 color = getPixelColor(device, 1, 1);
22394 ok(color == 0x00ffff00, "Got unexpected color 0x%08x.\n", color);
22395 color = getPixelColor(device, 700, 500);
22396 ok(color == 0x00ffff00, "Got unexpected color 0x%08x.\n", color);
22398 hr = IDirect3DDevice9_BeginScene(device);
22399 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22400 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
22401 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22402 hr = IDirect3DDevice9_EndScene(device);
22403 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22404 color = getPixelColor(device, 1, 1);
22405 ok(color == 0x0000ff00, "Got unexpected color 0x%08x.\n", color);
22406 color = getPixelColor(device, 700, 500);
22407 ok(color == 0x0000ff00, "Got unexpected color 0x%08x.\n", color);
22409 refcount = IDirect3DDevice9_Release(device);
22410 ok(!refcount, "Device has %u references left.\n", refcount);
22411 done:
22412 IDirect3D9_Release(d3d);
22413 DestroyWindow(window);
22416 static void test_drawindexedprimitiveup(void)
22418 static const struct vertex
22420 struct vec3 position;
22421 DWORD diffuse;
22423 quad[] =
22425 {{-1.0f, -1.0f, 0.1f}, 0xff00ff00},
22426 {{-1.0f, 1.0f, 0.1f}, 0xff0000ff},
22427 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
22428 {{ 1.0f, 1.0f, 0.1f}, 0xff0000ff},
22430 {{-1.0f, -1.0f, 0.1f}, 0xff0000ff},
22431 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
22432 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
22433 {{ 1.0f, 1.0f, 0.1f}, 0xff00ff00},
22435 static const unsigned short indices[] = {0, 1, 2, 3, 4, 5, 6, 7};
22436 IDirect3DDevice9 *device;
22437 IDirect3D9 *d3d;
22438 ULONG refcount;
22439 D3DCOLOR color;
22440 HWND window;
22441 HRESULT hr;
22443 window = create_window();
22444 d3d = Direct3DCreate9(D3D_SDK_VERSION);
22445 ok(!!d3d, "Failed to create a D3D object.\n");
22447 if (!(device = create_device(d3d, window, window, TRUE)))
22449 skip("Failed to create a D3D device.\n");
22450 IDirect3D9_Release(d3d);
22451 DestroyWindow(window);
22452 return;
22455 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
22456 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
22457 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
22458 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
22459 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
22460 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
22462 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
22463 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
22465 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
22466 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22468 hr = IDirect3DDevice9_BeginScene(device);
22469 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22470 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 4, 4, 2, indices + 4, D3DFMT_INDEX16, quad, sizeof(*quad));
22471 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22472 hr = IDirect3DDevice9_EndScene(device);
22473 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22475 color = getPixelColor(device, 160, 120);
22476 ok(color_match(color, 0x0040bf00, 1), "Got unexpected color 0x%08x.\n", color);
22477 color = getPixelColor(device, 480, 120);
22478 ok(color_match(color, 0x0040bf00, 1), "Got unexpected color 0x%08x.\n", color);
22479 color = getPixelColor(device, 160, 360);
22480 ok(color_match(color, 0x00404080, 1), "Got unexpected color 0x%08x.\n", color);
22481 color = getPixelColor(device, 480, 360);
22482 ok(color_match(color, 0x00bf4000, 1), "Got unexpected color 0x%08x.\n", color);
22484 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
22485 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22487 hr = IDirect3DDevice9_BeginScene(device);
22488 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22489 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 0, 4, 2, indices, D3DFMT_INDEX16, quad, sizeof(*quad));
22490 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22491 hr = IDirect3DDevice9_EndScene(device);
22492 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22494 color = getPixelColor(device, 160, 120);
22495 ok(color_match(color, 0x004000bf, 1), "Got unexpected color 0x%08x.\n", color);
22496 color = getPixelColor(device, 480, 120);
22497 ok(color_match(color, 0x004000bf, 1), "Got unexpected color 0x%08x.\n", color);
22498 color = getPixelColor(device, 160, 360);
22499 ok(color_match(color, 0x00408040, 1), "Got unexpected color 0x%08x.\n", color);
22500 color = getPixelColor(device, 480, 360);
22501 ok(color_match(color, 0x00bf0040, 1), "Got unexpected color 0x%08x.\n", color);
22503 refcount = IDirect3DDevice9_Release(device);
22504 ok(!refcount, "Device has %u references left.\n", refcount);
22505 IDirect3D9_Release(d3d);
22506 DestroyWindow(window);
22509 static void test_vertex_texture(void)
22511 static const D3DVERTEXELEMENT9 decl_elements[] =
22513 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
22514 D3DDECL_END()
22516 static const struct vec3 quad[] =
22518 {-1.0f, -1.0f, 0.0f},
22519 {-1.0f, 1.0f, 0.0f},
22520 { 1.0f, -1.0f, 0.0f},
22521 { 1.0f, 1.0f, 0.0f},
22523 static const DWORD vs_code[] =
22525 0xfffe0300, /* vs_3_0 */
22526 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0, 0, 0, 0 */
22527 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
22528 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
22529 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
22530 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
22531 0x0300005f, 0xe00f0001, 0xa0000000, 0xa0e40800, /* texldl o1, c0.x, s0 */
22532 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
22533 0x0000ffff, /* end */
22535 static const DWORD ps_code[] =
22537 0xffff0300, /* ps_3_0 */
22538 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color v0 */
22539 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
22540 0x0000ffff, /* end */
22542 static const DWORD texture_data[4] = {0x00ffff00, 0x00ffff00, 0x00ffff00, 0x00ffff00};
22543 IDirect3DVertexDeclaration9 *declaration;
22544 IDirect3DTexture9 *texture;
22545 IDirect3DVertexShader9 *vs;
22546 IDirect3DPixelShader9 *ps;
22547 IDirect3DDevice9 *device;
22548 D3DLOCKED_RECT lr;
22549 IDirect3D9 *d3d;
22550 D3DCOLOR color;
22551 ULONG refcount;
22552 D3DCAPS9 caps;
22553 HWND window;
22554 HRESULT hr;
22556 window = create_window();
22557 d3d = Direct3DCreate9(D3D_SDK_VERSION);
22558 ok(!!d3d, "Failed to create D3D object.\n");
22560 if (!(device = create_device(d3d, window, window, TRUE)))
22562 skip("Failed to create D3D device.\n");
22563 IDirect3D9_Release(d3d);
22564 DestroyWindow(window);
22565 return;
22568 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
22569 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
22570 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0) || caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
22572 skip("SM3 is not supported.\n");
22573 goto done;
22575 if (!(caps.VertexTextureFilterCaps & D3DPTFILTERCAPS_MAGFPOINT)
22576 || !(caps.VertexTextureFilterCaps & D3DPTFILTERCAPS_MINFPOINT))
22578 skip("Vertex texture point filtering is not supported, caps %#x.\n", caps.VertexTextureFilterCaps);
22579 goto done;
22581 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
22582 D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8);
22583 if (hr != D3D_OK)
22585 skip("No vertex texture fetch support for D3DFMT_A8R8G8B8, hr %#x.\n", hr);
22586 goto done;
22589 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
22590 ok(hr == D3D_OK, "Failed to create texture, hr %#x.\n", hr);
22591 memset(&lr, 0, sizeof(lr));
22592 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
22593 ok(hr == D3D_OK, "Failed to lock texture, hr %#x.\n", hr);
22594 memcpy(lr.pBits, texture_data, sizeof(texture_data));
22595 hr = IDirect3DTexture9_UnlockRect(texture, 0);
22596 ok(hr == D3D_OK, "Failed to unlock texture, hr %#x.\n", hr);
22598 hr = IDirect3DDevice9_SetTexture(device, D3DVERTEXTEXTURESAMPLER0, (IDirect3DBaseTexture9 *)texture);
22599 ok(hr == D3D_OK, "Failed to set texture, hr %#x.\n", hr);
22601 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &declaration);
22602 ok(SUCCEEDED(hr), "Failed to create vertex declaration, hr %#x.\n", hr);
22603 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
22604 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
22605 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
22606 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
22608 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration);
22609 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
22610 hr = IDirect3DDevice9_SetVertexShader(device, vs);
22611 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
22612 hr = IDirect3DDevice9_SetPixelShader(device, ps);
22613 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
22615 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
22616 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22617 hr = IDirect3DDevice9_BeginScene(device);
22618 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22619 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
22620 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22621 hr = IDirect3DDevice9_EndScene(device);
22622 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22623 color = getPixelColor(device, 160, 360);
22624 ok(color == texture_data[0], "Got unexpected color 0x%08x.\n", color);
22626 IDirect3DPixelShader9_Release(ps);
22627 IDirect3DVertexShader9_Release(vs);
22628 IDirect3DTexture9_Release(texture);
22629 IDirect3DVertexDeclaration9_Release(declaration);
22630 done:
22631 refcount = IDirect3DDevice9_Release(device);
22632 ok(!refcount, "Device has %u references left.\n", refcount);
22633 IDirect3D9_Release(d3d);
22634 DestroyWindow(window);
22637 static void test_mvp_software_vertex_shaders(void)
22639 IDirect3DVertexDeclaration9 *vertex_declaration;
22640 D3DPRESENT_PARAMETERS present_parameters = {0};
22641 IDirect3DVertexShader9 *pure_sw_shader = NULL;
22642 IDirect3DVertexShader9 *reladdr_shader = NULL;
22643 IDirect3DDevice9 *device;
22644 DWORD expected_color;
22645 IDirect3D9 *d3d;
22646 ULONG refcount;
22647 D3DCAPS9 caps;
22648 DWORD color;
22649 HWND window;
22650 HRESULT hr;
22652 static const float c_index[4] = {256.0f, 0.0f, 0.0f, 0.0f};
22653 static const float c_color[4] = {0.0f, 1.0f, 0.0f, 1.0f};
22654 static const DWORD reladdr_shader_code[] =
22656 0xfffe0200, /* vs_2_0 */
22657 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
22658 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c1, 1.0, 1.0, 1.0, 1.0 */
22659 0x0200002e, 0xb0010000, 0xa0000000, /* mova a0.x, c0.x */
22660 0x03000001, 0xd00f0000, 0xa0e42000, 0xb0000000, /* mov oD0, c[a0.x] */
22661 0x02000001, 0xd0040000, 0xa0e40001, /* mov oD0.z, c1 */
22662 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
22663 0x0000ffff /* END */
22665 static const DWORD pure_sw_shader_code[] =
22667 0xfffe0200, /* vs_2_0 */
22668 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
22669 0x05000051, 0xa00f0100, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c256, 1.0, 1.0, 1.0, 1.0 */
22670 0x02000001, 0xd00f0000, 0xa0e40100, /* mov oD0, c256 */
22671 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
22672 0x0000ffff /* END */
22675 static const struct
22677 float position[3];
22678 DWORD color;
22680 quad[] =
22682 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
22683 {{-1.0f, 1.0f, 0.0f}, 0xffff0000},
22684 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000},
22685 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
22687 static const D3DVERTEXELEMENT9 decl_elements[] =
22689 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
22690 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
22691 D3DDECL_END()
22694 window = create_window();
22695 d3d = Direct3DCreate9(D3D_SDK_VERSION);
22696 ok(!!d3d, "Failed to create a D3D object.\n");
22698 present_parameters.Windowed = TRUE;
22699 present_parameters.hDeviceWindow = window;
22700 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
22701 present_parameters.BackBufferWidth = 640;
22702 present_parameters.BackBufferHeight = 480;
22703 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
22704 present_parameters.EnableAutoDepthStencil = TRUE;
22705 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
22707 if (FAILED(IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
22708 D3DCREATE_MIXED_VERTEXPROCESSING, &present_parameters, &device)))
22710 skip("Failed to create a D3D device, skipping tests.\n");
22711 goto done;
22714 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
22715 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
22716 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
22718 skip("No vs_2_0 support, skipping tests.\n");
22719 IDirect3DDevice9_Release(device);
22720 goto done;
22723 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
22724 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
22726 hr = IDirect3DDevice9_SetSoftwareVertexProcessing(device, 0);
22727 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22729 hr = IDirect3DDevice9_CreateVertexShader(device, reladdr_shader_code, &reladdr_shader);
22730 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22731 hr = IDirect3DDevice9_CreateVertexShader(device, pure_sw_shader_code, &pure_sw_shader);
22732 todo_wine
22733 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22734 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
22735 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22736 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
22737 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22739 hr = IDirect3DDevice9_SetVertexShader(device, pure_sw_shader);
22740 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22742 hr = IDirect3DDevice9_BeginScene(device);
22743 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22744 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
22745 todo_wine
22746 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
22747 hr = IDirect3DDevice9_EndScene(device);
22748 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22750 expected_color = 0; /* Nothing rendered. */
22751 color = getPixelColor(device, 5, 5);
22752 todo_wine
22753 ok(color == expected_color, "Expected color 0x%08x, got 0x%08x (sw shader in hw mode).\n",
22754 expected_color, color);
22756 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
22757 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22758 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
22759 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22761 hr = IDirect3DDevice9_BeginScene(device);
22762 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22763 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
22764 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22765 hr = IDirect3DDevice9_EndScene(device);
22766 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22768 expected_color = 0x00ff0000; /* Color from vertex data and not from the shader. */
22769 color = getPixelColor(device, 5, 5);
22770 ok(color == expected_color, "Expected color 0x%08x, got 0x%08x (sw shader in hw mode, second attempt).\n",
22771 expected_color, color);
22773 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
22774 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22775 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
22776 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22778 hr = IDirect3DDevice9_BeginScene(device);
22779 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22780 hr = IDirect3DDevice9_SetSoftwareVertexProcessing(device, 1);
22781 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22782 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
22783 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22784 hr = IDirect3DDevice9_EndScene(device);
22785 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22787 expected_color = 0x00ffffff;
22788 color = getPixelColor(device, 5, 5);
22789 todo_wine
22790 ok(color == expected_color, "Expected color 0x%08x, got 0x%08x (sw shader in sw mode).\n",
22791 expected_color, color);
22793 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
22794 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22795 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
22796 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22798 hr = IDirect3DDevice9_SetSoftwareVertexProcessing(device, 0);
22799 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22800 hr = IDirect3DDevice9_SetVertexShader(device, reladdr_shader);
22801 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22803 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, c_index, 1);
22804 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22805 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, (unsigned int)c_index[0], c_color, 1);
22806 todo_wine
22807 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22809 hr = IDirect3DDevice9_BeginScene(device);
22810 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22811 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
22812 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22813 hr = IDirect3DDevice9_EndScene(device);
22814 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22816 /* Index 256 is out of bounds for selected shader in HW mode. c[256] is 0 most of the time. It
22817 is not guaranteed across all the adapters though, so disabling test. */
22818 #if 0
22819 expected_color = 0x000000ff;
22820 color = getPixelColor(device, 5, 5);
22821 ok(color == expected_color, "Expected color 0x%08x, got 0x%08x (shader in hw mode).\n",
22822 expected_color, color);
22823 #endif
22825 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
22826 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22827 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
22828 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22830 hr = IDirect3DDevice9_BeginScene(device);
22831 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22832 hr = IDirect3DDevice9_SetSoftwareVertexProcessing(device, 1);
22833 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
22834 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22835 hr = IDirect3DDevice9_EndScene(device);
22836 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
22838 expected_color = 0x0000ffff; /* c[256] is c_color for SW shader. */
22839 color = getPixelColor(device, 5, 5);
22840 todo_wine
22841 ok(color == expected_color, "Expected color 0x%08x, got 0x%08x (shader in sw mode).\n",
22842 expected_color, color);
22844 IDirect3DVertexDeclaration9_Release(vertex_declaration);
22845 IDirect3DVertexShader9_Release(reladdr_shader);
22846 if (pure_sw_shader)
22847 IDirect3DVertexShader9_Release(pure_sw_shader);
22848 refcount = IDirect3DDevice9_Release(device);
22849 ok(!refcount, "Device has %u references left.\n", refcount);
22850 done:
22851 IDirect3D9_Release(d3d);
22852 DestroyWindow(window);
22855 static void test_null_format(void)
22857 static const D3DVIEWPORT9 vp_lower = {0, 60, 640, 420, 0.0f, 1.0f};
22858 static const D3DVIEWPORT9 vp_560 = {0, 180, 560, 300, 0.0f, 1.0f};
22859 static const D3DVIEWPORT9 vp_full = {0, 0, 640, 480, 0.0f, 1.0f};
22860 static const DWORD null_fourcc = MAKEFOURCC('N','U','L','L');
22861 static const struct
22863 struct vec3 pos;
22864 DWORD diffuse;
22866 quad_partial[] =
22868 {{-1.0f, 0.5f, 0.1f}, 0x000000ff},
22869 {{ 0.5f, 0.5f, 0.1f}, 0x000000ff},
22870 {{-1.0f, -1.0f, 0.1f}, 0x000000ff},
22871 {{ 0.5f, -1.0f, 0.1f}, 0x000000ff},
22873 quad[] =
22875 {{-1.0f, 1.0f, 0.5f}, 0x00ff0000},
22876 {{ 1.0f, 1.0f, 0.5f}, 0x00ff0000},
22877 {{-1.0f, -1.0f, 0.5f}, 0x00ff0000},
22878 {{ 1.0f, -1.0f, 0.5f}, 0x00ff0000},
22880 quad_far[] =
22882 {{-1.0f, 1.0f, 1.0f}, 0x0000ff00},
22883 {{ 1.0f, 1.0f, 1.0f}, 0x0000ff00},
22884 {{-1.0f, -1.0f, 1.0f}, 0x0000ff00},
22885 {{ 1.0f, -1.0f, 1.0f}, 0x0000ff00},
22887 static const struct
22889 unsigned int x, y;
22890 D3DCOLOR color;
22891 BOOL todo;
22893 expected_colors[] =
22895 {200, 30, 0x0000ff00, FALSE},
22896 {440, 30, 0x0000ff00, FALSE},
22897 {520, 30, 0x0000ff00, FALSE},
22898 {600, 30, 0x0000ff00, FALSE},
22899 {200, 90, 0x00000000, FALSE},
22900 {440, 90, 0x0000ff00, FALSE},
22901 {520, 90, 0x0000ff00, FALSE},
22902 {600, 90, 0x0000ff00, FALSE},
22903 {200, 150, 0x000000ff, FALSE},
22904 {440, 150, 0x000000ff, FALSE},
22905 {520, 150, 0x0000ff00, FALSE},
22906 {600, 150, 0x0000ff00, FALSE},
22907 {200, 320, 0x000000ff, FALSE},
22908 {440, 320, 0x000000ff, FALSE},
22909 {520, 320, 0x00000000, TRUE},
22910 {600, 320, 0x0000ff00, FALSE},
22912 IDirect3DSurface9 *original_rt, *small_rt, *null_rt, *small_null_rt;
22913 IDirect3DDevice9 *device;
22914 IDirect3D9 *d3d;
22915 unsigned int i;
22916 D3DCOLOR color;
22917 HWND window;
22918 HRESULT hr;
22920 d3d = Direct3DCreate9(D3D_SDK_VERSION);
22921 ok(!!d3d, "Failed to create a D3D object.\n");
22923 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
22924 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, null_fourcc)))
22926 skip("No NULL format support, skipping NULL test.\n");
22927 IDirect3D9_Release(d3d);
22928 return;
22931 window = create_window();
22932 if (!(device = create_device(d3d, window, window, TRUE)))
22934 skip("Failed to create a D3D device.\n");
22935 IDirect3D9_Release(d3d);
22936 DestroyWindow(window);
22937 return;
22940 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
22941 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
22943 hr = IDirect3DDevice9_CreateRenderTarget(device, 400, 300, D3DFMT_A8R8G8B8,
22944 D3DMULTISAMPLE_NONE, 0, FALSE, &small_rt, NULL);
22945 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
22946 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, null_fourcc,
22947 D3DMULTISAMPLE_NONE, 0, FALSE, &null_rt, NULL);
22948 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
22949 hr = IDirect3DDevice9_CreateRenderTarget(device, 400, 300, null_fourcc,
22950 D3DMULTISAMPLE_NONE, 0, FALSE, &small_null_rt, NULL);
22951 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
22953 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
22954 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
22955 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
22956 ok(SUCCEEDED(hr), "Failed to enable depth test, hr %#x.\n", hr);
22957 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
22958 ok(SUCCEEDED(hr), "Failed to set depth function, hr %#x.\n", hr);
22959 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
22960 ok(SUCCEEDED(hr), "Failed to enable depth write, hr %#x.\n", hr);
22961 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
22962 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
22964 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
22965 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
22967 /* Clear extends to viewport size > RT size even if format is not
22968 * "NULL". */
22969 hr = IDirect3DDevice9_SetRenderTarget(device, 0, small_rt);
22970 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
22972 hr = IDirect3DDevice9_SetViewport(device, &vp_full);
22973 ok(hr == D3D_OK, "Failed to set viewport, hr %#x.\n", hr);
22975 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.2f, 0);
22976 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
22978 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
22979 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
22981 hr = IDirect3DDevice9_BeginScene(device);
22982 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
22983 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
22984 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
22985 hr = IDirect3DDevice9_EndScene(device);
22986 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
22988 hr = IDirect3DDevice9_SetRenderTarget(device, 0, null_rt);
22989 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
22990 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
22991 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
22993 /* Draw only extends to viewport size > RT size if format is "NULL". */
22994 hr = IDirect3DDevice9_SetRenderTarget(device, 0, small_rt);
22995 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
22996 hr = IDirect3DDevice9_SetViewport(device, &vp_lower);
22997 ok(hr == D3D_OK, "Failed to set viewport, hr %#x.\n", hr);
22998 hr = IDirect3DDevice9_BeginScene(device);
22999 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
23000 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
23001 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
23002 hr = IDirect3DDevice9_EndScene(device);
23003 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
23005 hr = IDirect3DDevice9_SetRenderTarget(device, 0, small_null_rt);
23006 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
23007 hr = IDirect3DDevice9_SetViewport(device, &vp_560);
23008 ok(hr == D3D_OK, "Failed to set viewport, hr %#x.\n", hr);
23009 hr = IDirect3DDevice9_BeginScene(device);
23010 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
23011 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
23012 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
23013 hr = IDirect3DDevice9_EndScene(device);
23014 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
23016 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
23017 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
23019 hr = IDirect3DDevice9_BeginScene(device);
23020 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
23021 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_partial, sizeof(*quad_partial));
23022 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
23023 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_far, sizeof(*quad_far));
23024 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
23025 hr = IDirect3DDevice9_EndScene(device);
23026 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
23028 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
23030 color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
23031 todo_wine_if(expected_colors[i].todo) ok(color_match(color, expected_colors[i].color, 1),
23032 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
23033 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
23036 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
23037 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
23039 IDirect3DSurface9_Release(small_null_rt);
23040 IDirect3DSurface9_Release(null_rt);
23041 IDirect3DSurface9_Release(small_rt);
23042 IDirect3DSurface9_Release(original_rt);
23043 cleanup_device(device);
23044 IDirect3D9_Release(d3d);
23047 START_TEST(visual)
23049 D3DADAPTER_IDENTIFIER9 identifier;
23050 IDirect3D9 *d3d;
23051 HRESULT hr;
23053 if (!(d3d = Direct3DCreate9(D3D_SDK_VERSION)))
23055 skip("could not create D3D9 object\n");
23056 return;
23059 memset(&identifier, 0, sizeof(identifier));
23060 hr = IDirect3D9_GetAdapterIdentifier(d3d, 0, 0, &identifier);
23061 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
23062 trace("Driver string: \"%s\"\n", identifier.Driver);
23063 trace("Description string: \"%s\"\n", identifier.Description);
23064 /* Only Windows XP's default VGA driver should have an empty description */
23065 ok(identifier.Description[0] || broken(!strcmp(identifier.Driver, "vga.dll")), "Empty driver description.\n");
23066 trace("Device name string: \"%s\"\n", identifier.DeviceName);
23067 ok(identifier.DeviceName[0], "Empty device name.\n");
23068 trace("Driver version %d.%d.%d.%d\n",
23069 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
23070 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
23072 IDirect3D9_Release(d3d);
23074 test_sanity();
23075 depth_clamp_test();
23076 stretchrect_test();
23077 lighting_test();
23078 test_specular_lighting();
23079 clear_test();
23080 color_fill_test();
23081 fog_test();
23082 test_cube_wrap();
23083 z_range_test();
23084 maxmip_test();
23085 offscreen_test();
23086 ds_size_test();
23087 test_blend();
23088 test_shademode();
23089 srgbtexture_test();
23090 release_buffer_test();
23091 float_texture_test();
23092 g16r16_texture_test();
23093 pixelshader_blending_test();
23094 texture_transform_flags_test();
23095 autogen_mipmap_test();
23096 fixed_function_decl_test();
23097 conditional_np2_repeat_test();
23098 fixed_function_bumpmap_test();
23099 test_pointsize();
23100 tssargtemp_test();
23101 np2_stretch_rect_test();
23102 yuv_color_test();
23103 yuv_layout_test();
23104 zwriteenable_test();
23105 alphatest_test();
23106 viewport_test();
23107 test_constant_clamp_vs();
23108 test_compare_instructions();
23109 test_mova();
23110 loop_index_test();
23111 sincos_test();
23112 sgn_test();
23113 clip_planes_test();
23114 test_vshader_input();
23115 test_vshader_float16();
23116 stream_test();
23117 fog_with_shader_test();
23118 texbem_test();
23119 texdepth_test();
23120 texkill_test();
23121 volume_v16u16_test();
23122 constant_clamp_ps_test();
23123 cnd_test();
23124 dp2add_ps_test();
23125 unbound_sampler_test();
23126 nested_loop_test();
23127 pretransformed_varying_test();
23128 vface_register_test();
23129 test_fragment_coords();
23130 multiple_rendertargets_test();
23131 texop_test();
23132 texop_range_test();
23133 alphareplicate_test();
23134 dp3_alpha_test();
23135 depth_buffer_test();
23136 depth_buffer2_test();
23137 depth_blit_test();
23138 intz_test();
23139 shadow_test();
23140 fp_special_test();
23141 depth_bounds_test();
23142 srgbwrite_format_test();
23143 update_surface_test();
23144 multisample_get_rtdata_test();
23145 zenable_test();
23146 fog_special_test();
23147 volume_srgb_test();
23148 volume_dxt5_test();
23149 add_dirty_rect_test();
23150 multisampled_depth_buffer_test();
23151 resz_test();
23152 stencil_cull_test();
23153 test_per_stage_constant();
23154 test_3dc_formats();
23155 test_fog_interpolation();
23156 test_negative_fixedfunction_fog();
23157 test_position_index();
23158 test_table_fog_zw();
23159 test_signed_formats();
23160 test_multisample_mismatch();
23161 test_texcoordindex();
23162 test_vertex_blending();
23163 test_updatetexture();
23164 test_depthbias();
23165 test_flip();
23166 test_uninitialized_varyings();
23167 test_multisample_init();
23168 test_texture_blending();
23169 test_color_clamping();
23170 test_line_antialiasing_blending();
23171 test_dsy();
23172 test_evict_bound_resources();
23173 test_max_index16();
23174 test_backbuffer_resize();
23175 test_drawindexedprimitiveup();
23176 test_vertex_texture();
23177 test_mvp_software_vertex_shaders();
23178 test_null_format();